From 1f2712e4de97836c6e99779486cad2be794228a6 Mon Sep 17 00:00:00 2001 From: Carlos Camargo Date: Fri, 1 Oct 2010 09:03:07 -0500 Subject: [PATCH] Adding evolvable hardware example --- Examples/drivers/blink/Makefile | 2 +- Examples/ehw4/logic/Makefile | 75 ++ Examples/ehw4/logic/counters.vhd | 147 +++ Examples/ehw4/logic/dpram624x1.ngc | 3 + Examples/ehw4/logic/dpram624x31.ngc | 3 + Examples/ehw4/logic/dpram624x32.ngc | 3 + Examples/ehw4/logic/ehw.ucf | 37 + Examples/ehw4/logic/ehw.v | 278 ++++++ Examples/ehw4/logic/evalfit_peripheral.vhd | 482 ++++++++++ Examples/ehw4/logic/mt.vhd | 191 ++++ Examples/ehw4/logic/reg_bank.v | 96 ++ Examples/ehw4/src/Makefile | 33 + Examples/ehw4/src/funlut.dat | Bin 0 -> 250 bytes Examples/ehw4/src/genetic.c | 816 ++++++++++++++++ Examples/ehw4/src/genetic.h | 126 +++ Examples/ehw4/src/puertas.dat | Bin 0 -> 125 bytes Examples/ehw4/src/sintesishw.h | 97 ++ Examples/ehw4/src/sintesishw_client.c | 461 +++++++++ Examples/ehw4/src/sintesishw_client.h | 64 ++ Examples/ehw4/src/sintesishw_server.c | 283 ++++++ Examples/ehw4/src/sintesishw_server.h | 58 ++ Examples/ehw4/src/test/Makefile | 29 + Examples/ehw4/src/test/enable_irq.c | 40 + Examples/ehw4/src/test/enable_rx.c | 40 + Examples/ehw4/src/test/jz47xx_gpio.c | 119 +++ Examples/ehw4/src/test/jz47xx_gpio.h | 84 ++ Examples/ehw4/src/test/jz47xx_gpio.o | Bin 0 -> 2984 bytes Examples/ehw4/src/test/jz47xx_mmap.c | 64 ++ Examples/ehw4/src/test/jz47xx_mmap.h | 17 + Examples/ehw4/src/test/jz47xx_mmap.o | Bin 0 -> 2156 bytes Examples/ehw4/src/test/jz_init_sram.c | 75 ++ Examples/ehw4/src/test/jz_test_gpio.c | 59 ++ Examples/ehw4/src/test/xburst | Bin 0 -> 57710 bytes Examples/ehw4/src/test/xburst.c | 70 ++ Examples/ehw4/src/test/xburst.h | 10 + KICAD_design_files/SAKC_PCB_v2/SAKC.drl | 908 +++++++++--------- binaries/reflash/Makefile | 10 +- .../logic/sakc/firmware/boot0-serial/Makefile | 1 + .../sakc/firmware/boot0-serial/image.lst | 454 --------- .../sakc/firmware/boot0-serial/image.srec | 44 - lm32/logic/sakc/system_tb.v | 4 +- plasma/bootldr/bootldr.c | 4 +- plasma/gpio/Makefile | 2 +- plasma/logic/ram_image.vhd | 182 ++-- 44 files changed, 4424 insertions(+), 1047 deletions(-) create mode 100644 Examples/ehw4/logic/Makefile create mode 100755 Examples/ehw4/logic/counters.vhd create mode 100644 Examples/ehw4/logic/dpram624x1.ngc create mode 100644 Examples/ehw4/logic/dpram624x31.ngc create mode 100644 Examples/ehw4/logic/dpram624x32.ngc create mode 100644 Examples/ehw4/logic/ehw.ucf create mode 100644 Examples/ehw4/logic/ehw.v create mode 100644 Examples/ehw4/logic/evalfit_peripheral.vhd create mode 100755 Examples/ehw4/logic/mt.vhd create mode 100644 Examples/ehw4/logic/reg_bank.v create mode 100644 Examples/ehw4/src/Makefile create mode 100644 Examples/ehw4/src/funlut.dat create mode 100644 Examples/ehw4/src/genetic.c create mode 100644 Examples/ehw4/src/genetic.h create mode 100644 Examples/ehw4/src/puertas.dat create mode 100644 Examples/ehw4/src/sintesishw.h create mode 100644 Examples/ehw4/src/sintesishw_client.c create mode 100644 Examples/ehw4/src/sintesishw_client.h create mode 100644 Examples/ehw4/src/sintesishw_server.c create mode 100644 Examples/ehw4/src/sintesishw_server.h create mode 100755 Examples/ehw4/src/test/Makefile create mode 100755 Examples/ehw4/src/test/enable_irq.c create mode 100755 Examples/ehw4/src/test/enable_rx.c create mode 100755 Examples/ehw4/src/test/jz47xx_gpio.c create mode 100755 Examples/ehw4/src/test/jz47xx_gpio.h create mode 100755 Examples/ehw4/src/test/jz47xx_gpio.o create mode 100755 Examples/ehw4/src/test/jz47xx_mmap.c create mode 100755 Examples/ehw4/src/test/jz47xx_mmap.h create mode 100755 Examples/ehw4/src/test/jz47xx_mmap.o create mode 100755 Examples/ehw4/src/test/jz_init_sram.c create mode 100755 Examples/ehw4/src/test/jz_test_gpio.c create mode 100755 Examples/ehw4/src/test/xburst create mode 100755 Examples/ehw4/src/test/xburst.c create mode 100755 Examples/ehw4/src/test/xburst.h delete mode 100644 lm32/logic/sakc/firmware/boot0-serial/image.lst delete mode 100755 lm32/logic/sakc/firmware/boot0-serial/image.srec diff --git a/Examples/drivers/blink/Makefile b/Examples/drivers/blink/Makefile index 1b31808..16e8242 100644 --- a/Examples/drivers/blink/Makefile +++ b/Examples/drivers/blink/Makefile @@ -1,7 +1,7 @@ EXTRA_CFLAGS += -Wall CC = mipsel-openwrt-linux-gcc OPENWRT_BASE = /home/cain/Embedded/ingenic/sakc/build/openwrt-xburst -KERNEL_SRC = $(OPENWRT_BASE)/build_dir/linux-xburst_qi_lb60/linux-2.6.32.10/ +KERNEL_SRC = $(OPENWRT_BASE)/build_dir/linux-xburst_qi_lb60/linux-2.6.32.16/ CROSS_COMPILE = mipsel-openwrt-linux- obj-m += blinker.o diff --git a/Examples/ehw4/logic/Makefile b/Examples/ehw4/logic/Makefile new file mode 100644 index 0000000..cf86aaa --- /dev/null +++ b/Examples/ehw4/logic/Makefile @@ -0,0 +1,75 @@ +DESIGN = ehw +PINS = $(DESIGN).ucf +DEVICE = xc3s500e-VQ100-4 +BGFLAGS = -g TdoPin:PULLNONE -g DonePin:PULLUP \ + -g CRC:enable -g StartUpClk:CCLK + +SIM_CMD = /opt/cad/modeltech/bin/vsim +SIM_COMP_SCRIPT = simulation/$(DESIGN)_TB.do +#SIM_INIT_SCRIPT = simulation/$(DESIGN)_init.do +SIMGEN_OPTIONS = -p $(FPGA_ARCH) -lang $(LANGUAGE) +SAKC_IP = 192.168.254.101 + +SRC = $(DESIGN).v reg_bank.v +SRC_HDL = evalfit_peripheral.vhd counters.vhd mt.vhd +all: bits + +remake: clean-build all + +clean: + rm -f *~ */*~ a.out *.log *.key *.edf *.ps trace.dat + +clean-build: clean + rm -rf build + +cleanall: clean + rm -rf build $(DESIGN).bit + +bits: $(DESIGN).bit + +# +# Synthesis +# +build/project.src: + @[ -d build ] || mkdir build + @rm -f $@ +#If you don't have logicores disable this line + cp *ngc build/ + for i in $(SRC); do echo verilog work ../$$i >> $@; done + for i in $(SRC_HDL); do echo VHDL work ../$$i >> $@; done + +build/project.xst: build/project.src + echo "run" > $@ + echo "-top $(DESIGN) " >> $@ + echo "-p $(DEVICE)" >> $@ + echo "-opt_mode Area" >> $@ + echo "-opt_level 1" >> $@ + echo "-ifn project.src" >> $@ + echo "-ifmt mixed" >> $@ + echo "-ofn project.ngc" >> $@ + echo "-ofmt NGC" >> $@ + echo "-rtlview yes" >> $@ + +build/project.ngc: build/project.xst $(SRC) + cd build && xst -ifn project.xst -ofn project.log + +build/project.ngd: build/project.ngc $(PINS) + cd build && ngdbuild -p $(DEVICE) project.ngc -uc ../$(PINS) + +build/project.ncd: build/project.ngd + cd build && map -pr b -p $(DEVICE) project + +build/project_r.ncd: build/project.ncd + cd build && par -w project project_r.ncd + +build/project_r.twr: build/project_r.ncd + cd build && trce -v 25 project_r.ncd project.pcf + +$(DESIGN).bit: build/project_r.ncd build/project_r.twr + cd build && bitgen project_r.ncd -l -w $(BGFLAGS) + @mv -f build/project_r.bit $@ +sim: + cd simulation; $(SIM_CMD) -do $(DESIGN)_TB.do + +upload: $(DESIGN).bit + scp $(DESIGN).bit root@$(SAKC_IP): diff --git a/Examples/ehw4/logic/counters.vhd b/Examples/ehw4/logic/counters.vhd new file mode 100755 index 0000000..d04614e --- /dev/null +++ b/Examples/ehw4/logic/counters.vhd @@ -0,0 +1,147 @@ +------------------------------------------------------------------------------- +-- -- +-- MT32 - Mersenne Twister -- +-- Copyright (C) 2007 HT-LAB -- +-- -- +-- Contact : Use feedback form on the website. -- +-- Web: http://www.ht-lab.com -- +-- -- +-- MT32 files are released under the GNU General Public License. -- +-- -- +------------------------------------------------------------------------------- +-- -- +-- This library is free software; you can redistribute it and/or -- +-- modify it under the terms of the GNU Lesser General Public -- +-- License as published by the Free Software Foundation; either -- +-- version 2.1 of the License, or (at your option) any later version. -- +-- -- +-- This library is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- +-- Lesser General Public License for more details. -- +-- -- +-- Full details of the license can be found in the file "copying.txt". -- +-- -- +-- You should have received a copy of the GNU Lesser General Public -- +-- License along with this library; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------- +-- -- +-- Counters, instantiated in top level -- +------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.all; +USE ieee.std_logic_arith.all; +USE ieee.std_logic_unsigned.all; + +ENTITY counters IS + GENERIC( + M : integer := 397; + N : integer := 623 + ); + PORT( + clk : IN std_logic; + resetn : IN std_logic; + ena : IN std_logic; + wea : OUT std_logic; + kk_cnt : OUT std_logic_vector (9 DOWNTO 0); + km_cnt : OUT std_logic_vector (9 DOWNTO 0); + kp_cnt : OUT std_logic_vector (9 DOWNTO 0); + wr_cnt : OUT std_logic_vector (9 DOWNTO 0) + ); + +END counters ; + +-- +ARCHITECTURE rtl OF counters IS + +signal kk_cnt_s : std_logic_vector (9 DOWNTO 0); +signal km_cnt_s : std_logic_vector (9 DOWNTO 0); +signal kp_cnt_s : std_logic_vector (9 DOWNTO 0); + +signal wr_cnt_s : std_logic_vector (9 DOWNTO 0); + +BEGIN + +process (clk,resetn) + begin + if (resetn='0') then + wea <= '0'; + elsif (rising_edge(clk)) then + wea <= ena; -- wea is delayed by 1 clock cycle to + end if; -- prevent writing outside the dpram address +end process; -- address range (0..623) + + +------------------------------------------------------------------------------- +-- Write counter which is equal to kk-1 +-- Required to achieve single cycle read/write +------------------------------------------------------------------------------- +process (clk,resetn) + begin + if (resetn='0') then + wr_cnt_s <= (others => '1'); + elsif (rising_edge(clk)) then + if (wr_cnt_s = CONV_STD_LOGIC_VECTOR(N,10)) then + wr_cnt_s <= (others => '0'); + elsif ena='1' then + wr_cnt_s <= wr_cnt_s + '1'; + end if; + end if; +end process; +wr_cnt <= wr_cnt_s; + + +------------------------------------------------------------------------------- +-- kk Counter +------------------------------------------------------------------------------- +process (clk,resetn) + begin + if (resetn='0') then + kk_cnt_s <= (others => '0'); + elsif (rising_edge(clk)) then + if (kk_cnt_s = CONV_STD_LOGIC_VECTOR(N,10)) then + kk_cnt_s <= (others => '0'); + elsif ena='1' then + kk_cnt_s <= kk_cnt_s + '1'; + end if; + end if; +end process; +kk_cnt <= kk_cnt_s; + +------------------------------------------------------------------------------- +-- kp Counter +------------------------------------------------------------------------------- +process (clk,resetn) + begin + if (resetn='0') then + kp_cnt_s <= "0000000001"; + elsif (rising_edge(clk)) then + if (kp_cnt_s = CONV_STD_LOGIC_VECTOR(N,10)) then + kp_cnt_s <= (others => '0'); + elsif ena='1' then + kp_cnt_s <= kp_cnt_s + '1'; + end if; + end if; +end process; +kp_cnt <= kp_cnt_s; + +------------------------------------------------------------------------------- +-- km Counter +------------------------------------------------------------------------------- +process (clk,resetn) + begin + if (resetn='0') then + km_cnt_s <= CONV_STD_LOGIC_VECTOR(M,10); + elsif (rising_edge(clk)) then + if (km_cnt_s = CONV_STD_LOGIC_VECTOR(N,10)) then + km_cnt_s <= (others => '0'); + elsif ena='1' then + km_cnt_s <= km_cnt_s + '1'; + end if; + end if; +end process; +km_cnt <= km_cnt_s; + +end architecture rtl; diff --git a/Examples/ehw4/logic/dpram624x1.ngc b/Examples/ehw4/logic/dpram624x1.ngc new file mode 100644 index 0000000..7b72fe7 --- /dev/null +++ b/Examples/ehw4/logic/dpram624x1.ngc @@ -0,0 +1,3 @@ +XILINX-XDB 0.1 STUB 0.1 ASCII +XILINX-XDM V1.4e +$33;4g<,[o}e~g`n;"2*413&;$>"9 > %38416<89:;<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;<=>?01234567<91;<=>?012351739<::<=?>41771162=<;?8<>;55671537<3;KMTPR=IMNYM1?=:1<20>742@D[YY4NDEPA844=87>;7<::14631526<9;>88;;457250379=??=9:?416754269<:>==::11635422841;KMTPR=lk7<7>11192>LHW]]0|io2?:1<24>4=AGZ^X7JFA=394;773;0BB][[:EKA84<768;0>7AZTQWW>AIF480;201874586;29:6D@_UU8gmkd;;90;2<;4308LQQVR\3ndyyo33183:43<;80DYY^ZT;flqqd;;90;2i5;==?;11320063<<:?==?;152645228=??99?;0:624132==??<<:?54330572==8::1462402788::<9;?1573553399:?89;;5063?0228=?;<<>:502205238=?;=8?>44731466=<;?9=>:0037156399::9=:?10770==FLMXJ0=06;@FGVD:68730MIJ]A=32:g=FLMXJ0<<50?;8EABUI5;9255NDEPB848?3HNO^L2=>99B@ATF4:437LJKR@>7:==FLMXJ0807;@FGVD:1611JHI\N<6<;?DBCZH63255NDEPB8<8?3HNO^O2?>89B@ATE48:556OKDS@?548e3HNO^O2>2;2==>GCL[H7=?07;@FGVG:6611JHI\M<3<;?DBCZK68255NDEPA818?3HNO^O2:>99B@ATE4?437LJKRC>4:==FLMXI0507;@FGVG:>6:1J@A=4BT0;?GSTW@DMC<<4CIG@OZJNKLDXIRZVPD68GIMF<2IGGO74CNONMQRBL8>0OB\J_FGMAWGSAFDTECH@7:AQADRBL?1OEL2?>99GMD:6294=7IGN<0<5?AOE49437IGM<083:3=CAK6:2;5KO@>3:==CGH6:6=09;EMB84813MEI0=07;EMA84<76?1OCO2>>29FJD5;7:KMMQY7=>1BBDZP0758MKOSW9=<7D@FT^2;3>OIA]U;5:5FNHV\4D11BBDZP1758MKOSW8=<7D@FT^3;3>OIA]U:5:5FNHV\5D1D69JJLRX9L=0ECG[_0D4?LHN\V8;;6GAIU]152=NF@^T>?94IOKW[7503@DBXR<;7:KMMQY5=>1BBDZP2758MKOSW;=<7D@FT^0;3>OIA]U95:5FNHV\6D11BBDZP3758MKOSW:=<7D@FT^1;3>OIA]U85:5FNHV\7D1L8;HLJPZ5D?2CEEYQKfbfx]i}fooa8Ilhhz_oydaa2:L27>H68:1E=<:4N0320>H69;>0B86@>1768J470<2D:=5:4N03:7>H6:=1E=?>;;O3111=I9;33G;95>5A1268J457<2D:?<:4N0110>H6;:>0B<=;4:L27023668J45?<2D:?4=4N067?K738=1E=9?;;O3761=I9=9?7C?;459M51333G;?:95A1557?K730=1E=97<;O360>H6=9>0B<;>4:L21725568J432;2D::>5A1618J4>43G;2>6@=3:L146=I:890B?<<;O007>H5<:1E>8=4N340?K40;2D94>5A2808J653:L066=I;:90B>:<;O167>H4>:1E?:=4N2:0?K5>:2D??6@;029M0455\IL]@KIJN[@EESNFJCJ48WJSUKL=0__XNL^C4?VTQIEUI86]\R@68WVTE<2^R\H:>;T2,fimXelgTkh`jr`vlv*pfd`n%o~z}/scnhjiwS9W%~lc!r.t1*wgj'mz9t? }al61?P6(jeaTahcPgdlfvdrhz&|j`dj!crvq+wgjdfe{W<>R.scn*w)q:'xja"j2y0-vdk3:2_;#obd_lgn[bcim{kc!yamkg*fusz&xjaaa`pZ32Y+tfe'x$z? }al-gt7~5&{kf8?5Z0.`ooZkbeVmnbh|ntnp,rdjnl'ixx!}alnlku]6:T$ym` }/w0-vdk(ly8s>#|nm508Q5)edbUfi`Qheogqeqiu'kgei lsup,vdkkgfzP=>S!r`o-v*p5&{kf#i~=x3,qeh253\:$naePmdo\c`hbzh~d~"xnlhf-gvru'{kf`ba[06^*wgj&{%}>#|nm.fs6}4)zhg?>6[?/cnh[hcjWnoeio{os-ueioc&jy~"|nmmmlt^72U'xja#| v3,qeh)cx;r9"ob409V4*dkcVgnaRijndpbpjt(~hfbh#m|ts-qehjhgyQ:Q#|nm/p,r7(uid%o|?v=.scn04=R8&hggRcjm^efj`tf|fx$zlbfd/appw)uidfdc}U=]/pbi+t(~;$ym`!kp3z1*wgj<81^<"lck^ofiZabflxjxb| v`nj`+et|{%ym`b`oqY0Y+tfe'x$z? }al-gt7~5&{kf8<5Z0.`ooZkbeVmnbh|ntnp,rdjnl'ixx!}alnlku]3U'xja#| v3,qeh)cx;r9"ob409V4*dkcVgnaRijndpbpjt(~hfbh#m|ts-qehjhgyQ>Q#|nm/p,r7(uid%o|?v=.scn04=R8&hggRcjm^efj`tf|fx$zlbfd/appw)uidfdc}U9]/pbi+t(~;$ym`!kp3z1*wgj<81^<"lck^ofiZabflxjxb| v`nj`+et|{%ym`b`oqY4Y+tfe'x$z? }al-gt7~5&{kf8<5Z0.`ooZkbeVmnbh|ntnp,rdjnl'ixx!}alnlku]?U'xja#| v3,qeh)cx;r9"ob409V4*dkcVgnaRijndpbpjt(~hfbh#m|ts-qehjhgyQ2Q#|nm/p,r7(uid%o|?v=.scne>STM[UJ@DO\c:WPAWYQAZCI@H=4VBA:?SOB_V^R\H=4WDC0?RCEj2]YEYKPFHPPPf=PZ@^NS@AKE^C`?RTN\LUFCIKPB0f8\LJNFQ'SHO.?.0"PPPD'8';+M^MFI79[WQJNJ>1S_YQHNE58\VRX^JIi7UQLOSG\MK@H>2RonRGkf:ZglZVuad\n~~g`n028\akXEh`d~[k}shmm55=_ldUFeca}Vdppmjh?3hno~l&?)99b`atf 8#37ljkr`*1-==flmxj$>'7;`fgvd.3!11jhi|n(4+;?dbczh"=%55ndepb,2/?3hno~l&7)99b`atf 0#37ljkr`>3:==flmxj0<07;`fgvd:5611jhi|n<2<;?dbczh6?255ndepb808?3hno~l29>99b`atf4>437ljkr`>;:d=flmxj044?>99b`atf40437ljkrc*3-==flmxi$<'7;`fgvg.5!11jhi|m(2+;?dbczk"?%55ndepa,0/?3hno~o&9)99b`ate >#37ljkrc*;-==flmxi$4'7;`fgvg:7611jhi|m<0<;?dbczk69255ndepa868?3hno~o2;>99b`ate4<437ljkrc>5:==flmxi0:07;`fgvg:?6h1jhi|m<883:==flmxi040=f:`ooZkbeVmnbRx>_0.#\ljnfq*HC_K/Gdlfvdrhz);;"< ?3228gdb(x{erinz`s.ow77)cx{kf"zbp.]`c*bwzhg=>9v>.oel0>ekch>0oaem7:fjjd.7!>1oeco'1(:8`lhf 8:"46jfn`*25,>bnfh":9$64dhlb,40.02nbbl&>7(:8`lhf 82"46jfn`*2=,1:'7;ekme-4?!11oeco'28+4?aoii!9"46jfn`*04,13:==cagk7==07;ekme976611oeco313<;?aoii5;8255kioc?518?3mcem1?:>99gmkg;9?437igaa=34:==cagk7=507;ekme97>6>1oeco31?:8`lhf4;:546jfn`>15;>bnfh699364dhlb870902nbbl2=7?:8`lhf4;2546jfn`>1=;11oeco37?58`lhf414<7igaa=;=3>bnfk";%:5kio`+5,>&8:fjjg.69 20hd`m(00*<>bnfk":?$64dhla,42.02nbbo&>5(:8`lhe 8<"46jfnc*23,>8'7;ekmf-41!11oecl'26+;?aoij!83%55kio`+63me~xl&>5(;8`jssi!;=%45kotvb,41.12ndyyo'19+:?air|h":5$64dnwwe-4.12ndyyo'21+:?air|h"9=$74dnwwe-45!01ocxzn(31*=>bh}}k#>9'6;emvpd.5= 30hb{{a)05-<=cg|~j$?9&9:flqqg/:1#27iazt`*1=,>c9gkprf4::1<364dnwwf-6.02ndyyl'1(;8`jssj!;;%45kotva,47.12ndyyl'13+:?air|k":?$74dnwwf-73!01ocxzm(07*=>bh}}h#=;'6;emvpg.6? 30hb{{b)3;-<=cg|~i$<7&8:flqqd/: 30hb{{b)03-<=cg|~i$??&9:flqqd/:;#27iaztc*17,?3me~xo&=7(;8`jssj!83%45kotva,7?.02ndyyl'3(;8`jssj!9;%55kotva,1/?3me~xo&:)99gkpre ?#37iaztc*4-==cg|~i$5'7;emvpg.>!11ocxzm<1<:?air|k6:<374dnwwf976601ocxzm<00==>bh}}h7=>06;emvpg:6<730hb{{b=36:<=cg|~i0<819:flqqd;9>427iaztc>2<;?99gkpre48427iaztc>14;?>89gkpre4;8556j`uu`?668>3me~xo2=4?;8`jssj58>245kotva870912ndyyl326<:?air|k694374dnwwf94>611ocxzm<319:flqqd;;9437iaztc>0:==cg|~i0907;emvpg:2611ocxzm<7<;?air|k6<255kotva8=8?3me~xo26>`9gtwgj>;>s=?;4dqpbi343p8&i`fQbel]dakYq9V;'BB@J,OMMA7`53mzym`8=4y3/fimXelgTkh`Pv0]2(~eX`hyT~hilec?3(fYoizUyijmja<2/gZkbeV~r|h3>,b]kevYj}qUdyy~zt^pfcv;7$jU{~dcPtxrf94*dWzceeyoPv`n>4)eXzlkoSzgkti]a967+kVxnmiQxievk[d;49%iThd}nbmg\sdtiWkb}Snacl<2/gZoia}UmeakPn`of9avuid<98u?!mhd/gZqua}oTabjj_c?TVLRBWOCY_Y"l_vpjp`YjgmoTm0Y]IUG\BLTT\%iT`bok_hljpZ`ndl7: nQxrhvf[acw|aUi1;<;,b]tvlrbWmo{xeQn=707(fYoizUxl20-a\lduX{zxj1="l_`fgvdYpam~c1<>#c^cg`wdX`nd0??,b]gacgrd}Uomyo20-a\eiahz`~ca0>#c^fjwddkmV}j~cQmhw]qekab59&hSeo|_lgn[jssx|~T~hi|=1.`[rtn|lU|eizg_c?05)eX{ciRyfduj\e856$jUyiljPddrwlZd:>;>'oR|jae]gauroWh7=>9"l_c{waZunrl72 nQ|il]`kijn{`eeSnfjcj?BHI*dWjefab`Pcmi>4)eXlkT{dj{h<3/gZnf{Voen0>#c^uffZqnl}b6=!mPh`q\akg:8%iTd`ftc]uei;7$jef|b`jnu]mehc:lyxja;<;x0.`[pubWksiRyjb<2/gZstmVhrxhQxe`?3(fYr{lUoikozlu]geqg:8%w9=6jr`o561~6Wkf`S`kb_fgm[s7X9VrxxR?7;dfjb7h`l:1nbl=4eo`;?kadj|cgh;5}efafe3=umninn95|ssc7?vuuj?1|il&?)99tad:7294=7zkn<1<5?rce 9#37zkm<183:xFGx=h=7MNw1579B?2=9rY8o76?6zl25=<63g;:57:4$035>4763tY8m76?6:Q;b?47m3:1=>702Y8m76?8:f142<7280:w^=l:32a>1<6;;h65?8?1/==l5919U541=:r2=7?4u8094>{#mm0:86l=0683>03=;3?>wE??9:X02?3|i3?1:7?<:029y!`02;:<7)?>5;370>o59:0;6)ki:337?kcb2910e<<<:18'ac<6:m1eih4?;:k267<72-om6<4=2183>!ca288o7ckj:298m47a290/ik4>2e9ma`<332c:=h4?:%ge>44c3gon6854i03g>5<#mo0:>i5aed85?>o69j0;6)ki:00g?kcb2>10e<=3683>!ca28>97ckj:098m451290/ik4>439ma`<532c:?84?:%ge>4253gon6>54i017>5<#mo0:8?5aed87?>o6;:0;6)ki:061?kcb2<10e<==:18'ac<6<;1eih49;:k274<72-om6<:=;ogf>2=2g83>!ca28>97ckj:898k4c7290/ik4>fd9ma`<732e:hh4?:%ge>4`b3gon6<54o0fg>5<#mo0:jh5aed81?>i6lj0;6)ki:0df?kcb2:10c0=d983>!ca28ln7ckj:698k4b0290/ik4>fd9ma`4`b3gon6454o0f6>5<#mo0:jh5aed8b?>i6l:0;6)ki:0df?kcb2k10ca=cg83>!ca28ln7ckj:g98k4eb290/ik4>fd9ma`<6821d=nj50;&fb?7am2dni7?>;:m2gf<72-om644<3f;hn7>5$dd95cc54o0ab>5<#mo0:jh5aed820>=h9l<1<7*jf;3ea>hbm3;>76a>e483>!ca28ln7ckj:048?j7b<3:1(hh51gg8j`c=9>10c8:9l5`4=83.nj7?ie:lfa?7>32e:i<4?:%ge>4`b3gon6i6k10;6)ki:0df?kcb28o07d?;6;29?l73?3:17d?90;29 ``=9>o0bhk50:9j50c=83.nj7?8e:lfa?7<3`;>h7>5$dd952c65f14a94?"bn3;=n9<21<7*jf;34a>hbm3=07d?:7;29 ``=9>o0bhk58:9j500=83.nj7?8e:lfa??<3`;>97>5$dd952c=n9=l1<7*jf;34a>hbm3l07d?;e;29 ``=9>o0bhk51198m42c290/ik4>7d9ma`<6921b=9m50;&fb?70m2dni7?=;:k20g<72-om6<9j;ogf>45<3`;?m7>5$dd952c5<#mo0:;h5aed821>=n9??1<7*jf;34a>hbm3;=76g>6583>!ca28=n7ckj:058?l71;3:1(hh516g8j`c=9110e<8=:18'ac<6?l1eih4>9:9j537=83.nj7?8e:lfa?7f32c:9k4?:%ge>41b3gon626=4+eg823`=iml0:h65f15:94?"bn3;d68h0;6<4?:1yK55?<,o=1==o4oda94?=zj=i1<7?50;2xL46>3-l<69m4o5`94?=zj:?1<77n:00912}O9930V>8511yb>g<22?0:>7?<:02954<6:3;86l4m:485>46=980v(k9521c8 61=:920(>l521;8 `?=mk1b>=m50;9j65b=831b>=h50;9j646=831b><=50;&fb?46<2dni7>4;h022?6=,ll1><94ndg94>=n9;91<7*jf;31`>hbm3:07d?=2;29 ``=9;n0bhk51:9j577=83.nj7?=d:lfa?4<3`;9<7>5$dd957b=n98h1<7*jf;31`>hbm3207d?>a;29 ``=9;n0bhk59:9j56>=83.nj7?;2:lfa?6<3`;8;7>5$dd95146`je;08?l74=3:1(hh51508j`c=;21b=>:50;&fb?73:2dni7:4;h307?6=,ll1=9<4ndg91>=n9:81<7*jf;376>hbm3<07d?<1;29 ``=9=80bhk57:9j566=83.nj7?;2:lfa?><3`;9j7>5$dd9514=h9kk1<7*jf;3`3>hbm3>07b?m9;29 ``=9j=0bhk55:9l5g>=83.nj7?l7:lfa?0<3f;i;7>5$dd95f1=h9k;1<7*jf;3`3>hbm3i07b?m0;29 ``=9j=0bhk5d:9l5d`=83.nj7?l7:lfa?c<3f;ji7>5$dd95f1i6ij0;6)ki:0a4?kcb28;07b?nb;29 ``=9j=0bhk51398k4gf290/ik4>c69ma`<6;21d=l750;&fb?7d?2dni7?;;:m2g0<72-om643<3f;h87>5$dd95f15<#mo0:o:5aed823>=h9j81<7*jf;3`3>hbm3;376a>c083>!ca28i<7ckj:0;8?j7d83:1(hh51b58j`c=9h10c1eih4>b:9l5g5=83.nj7?l7:lfa?7d32e:m54?:%ge>4e03gon6dd83>!ca28ln7ckj:098k4bc290/ik4>fd9ma`<532e:hn4?:%ge>4`b3gon6>54o0fa>5<#mo0:jh5aed87?>i6lh0;6)ki:0df?kcb2<10c2=d783>!ca28ln7ckj:898k4b2290/ik4>fd9ma`4?:%ge>4`b3gon6o54o0f1>5<#mo0:jh5aed8`?>i6l80;6)ki:0df?kcb2m10cc=i6kj0;6)ki:0df?kcb28807b?lb;29 ``=9oo0bhk51298k4ef290/ik4>fd9ma`<6<21d=h850;&fb?7am2dni7?:;:m2a0<72-om640<3f;n87>5$dd95cc5<#mo0:jh5aed82<>=h9l81<7*jf;3ea>hbm3;276a>e083>!ca28ln7ckj:0c8?j7cn3:1(hh51gg8j`c=9k10cc:9l5f?=83.nj7?ie:lfa?7c32e:o54?:%ge>4`b3gon65;h354?6=,ll1=:k4ndg94>=n9hbm3;07d?:d;29 ``=9>o0bhk52:9j50e=83.nj7?8e:lfa?5<3`;>n7>5$dd952c21b=8650;&fb?70m2dni794;h363?6=,ll1=:k4ndg9<>=n9<<1<7*jf;34a>hbm3307d?:5;29 ``=9>o0bhk5a:9j505=83.nj7?8e:lfa?d<3`;>>7>5$dd952co6=4+eg823`=iml0:=65f15a94?"bn3;o6o0bhk51598m401290/ik4>7d9ma`<6=21b=;;50;&fb?70m2dni7?9;:k221<72-om6<9j;ogf>41<3`;=?7>5$dd952c5<#mo0:;h5aed82=>=n9?;1<7*jf;34a>hbm3;j76g>5g83>!ca28=n7ckj:0`8?l72<3:1(hh516g8j`c=9j10e<:6:18'ac<6?l1eih4>d:9j51>=83.nj7?8e:lfa?7b32c:5k4?:%ge>4g13gon6=54i0;g>5<#mo0:m;5aed82?>o61j0;6)ki:0c5?kcb2;10e<7m:18'ac<6i?1eih4<;:k2=d<72-om61=76g>9983>!ca28k=7ckj:798m4?0290/ik4>a79ma`<032c:5;4?:%ge>4g13gon6554i0;6>5<#mo0:m;5aed8:?>o61=0;6)ki:0c5?kcb2h10e<7=:18'ac<6i?1eih4m;:k2=4<72-om6f=8g83>!ca28k=7ckj:d98m4>b290/ik4>a79ma`4g13gon6<>4;h3;g?6=,ll1=l84ndg954=65f19c94?"bn3;j:6`je;30?>o6000;6)ki:0c5?kcb28>07d?n5;29 ``=9h<0bhk51498m4g3290/ik4>a79ma`<6>21b=l=50;&fb?7f>2dni7?8;:k2e7<72-om64><3`;j=7>5$dd95d05<#mo0:m;5aed82e>=n90o1<7*jf;3b2>hbm3;i76g>9283>!ca28k=7ckj:0a8?l7?03:1(hh51`48j`c=9m10e<68:18'ac<6i?1eih4>e:9a545=83;1<7>t$g590f=O9880D<>6;n6a>5<51;294~"a?3;;m6F>139K55?=k3n1i7h5}%d0>4=#n=0:7):k:39'0`<53->m6?5+5181?!362;1/9?4=;%70>7=#==097);::39'13<53-?<6?5+5981?!3>2;1/9l4=;%7a>7=#=j097);k:39'1`<53-?m6?5+6181?!062;1/:?4=;%40>7=#>=097)8::39'23<53-<<6?5+6981?!0>2;1/:l4=;%4a>7=#>j097)8k:39'2`<53-7=#?=097)9::39'33<53-=<6?5+7981?!1>2;1/;l4=;%5a>7=#?j097)9k:39'3`<53-=m6?5+8181?!>62;1/4?4=;%:0>7=#0=097)6::39'<3<53-2<6?5+8981?!>>2;1/4l4=;%324?77m2.3n7<4$g3971=#0m0:7)6j:09'55`=99o0(5m52:k0l:188m46c2900e7=3=10e?>50;&fb?7e3gon6554i0d94?"bn3;i7ckj:898m4c=83.nj7?m;ogf>d==83.nj7<6;ogf>4==50;&fb?4>3gon6>54i2094?"bn3827ckj:598m67=83.nj7<6;ogf>0=3gon6:54i3g94?"bn3827ckj:998m7b=83.nj7<6;ogf><=3gon6o54i3494?"bn3827ckj:b98m6`=83.nj7=j;ogf>5=:7ckj:098k13=83.nj7:;;ogf>5=<7ckj:098yg`c2909m7>50z&e3?`73A;:>6F>089Y73<1s>036n4k:d8e>x"a;3;0(k:51:&7`?4<,=o1>6*;f;08 06=:2.>=7<4$4096>"2;380(8:52:&61?4<,<<1>6*:7;08 0>=:2.>57<4$4c96>"2j380(8m52:&6`?4<,6*:f;08 36=:2.==7<4$7096>"1;380(;:52:&51?4<,?<1>6*97;08 3>=:2.=57<4$7c96>"1j380(;m52:&5`?4<,?o1>6*9f;08 26=:2.<=7<4$6096>"0;380(::52:&41?4<,><1>6*87;08 2>=:2.<57<4$6c96>"0j380(:m52:&4`?4<,>o1>6*8f;08 =6=:2.3=7<4$9096>"?;380(5:52:&;1?4<,1<1>6*77;08 =>=:2.357<4$9c96>"6990:0(5j51:&;a?7<,8:m6<>j;%:`>7=n;10;66g<9;29?l2>2900e9o50;9jb0<722cm:7>5;h33g?6=3`;;h7>5;h3`>5<#mo0:n6`je;28?l7f290/ik4>b:lfa?7<3`;26=4+eg82f>hbm3807d<::18'ac<6j2dni7=4;h07>5<#mo0:n6`je;68?l44290/ik4>b:lfa?3<3`896=4+eg82f>hbm3<07d<>:18'ac<6j2dni794;h03>5<#mo0:n6`je;:8?l7a290/ik4>b:lfa??<3`;n6=4+eg82f>hbm3k07d?k:18'ac<6j2dni7l4;h3;>5<#mo0:n6`je;a8?l4f290/ik4=9:lfa?6<3`836=4+eg81=>hbm3;07d<8:18'ac<512dni7<4;h10>5<#mo0956`je;18?l55290/ik4=9:lfa?2<3`9:6=4+eg81=>hbm3?07d=?:18'ac<512dni784;h0e>5<#mo0956`je;58?l4b290/ik4=9:lfa?><3`8o6=4+eg81=>hbm3307d5<#mo0956`je;`8?l41290/ik4=9:lfa?e<3`9m6=4+eg80a>hbm3:07d=k:18'ac<4m2dni7?4;h61>5<#mo0?=6`je;28?l27290/ik4;1:lfa?7<3f>>6=4+eg870>hbm3:07b:<:18'ac<3<2dni7?4;n6;>5<#mo0?;6`je;28?j21290/ik4;7:lfa?7<3thmo7>52`83>5}#n>0m<6F>139K55?4>;%d7>4=#4=;%77>7=#=<097);9:39'12<53-?36?5+5881?!3f2;1/9o4=;%7`>7=#=m097);j:39'1c<53-<;6?5+6081?!052;1/:>4=;%47>7=#><097)89:39'22<53-<36?5+6881?!0f2;1/:o4=;%4`>7=#>m097)8j:39'2c<53-=;6?5+7081?!152;1/;>4=;%57>7=#?<097)99:39'32<53-=36?5+7881?!1f2;1/;o4=;%5`>7=#?m097)9j:39'3c<53-2;6?5+8081?!>52;1/4>4=;%:7>7=#0<097)69:39'<2<53-236?5+8881?!>f2;1/=<>511g8 =d=:2.m=7=;;%:g>4=#0l0:7)??f;33a>"?k380e>650;9j7<<722c?57>5;h6b>5<>o68j0;66g>0e83>>o6k3:1(hh51c9ma`<732c:m7>5$dd95g=iml0:76g>9;29 ``=9k1eih4=;:k11?6=,ll1=o5aed80?>o5<3:1(hh51c9ma`<332c9?7>5$dd95g=iml0>76g=2;29 ``=9k1eih49;:k15?6=,ll1=o5aed84?>o583:1(hh51c9ma`5$dd95g=iml0276g>e;29 ``=9k1eih4n;:k2`?6=,ll1=o5aed8a?>o603:1(hh51c9ma`5$dd96<=iml0;76g=8;29 ``=:01eih4>;:k13?6=,ll1>45aed81?>o4;3:1(hh5289ma`<432c8>7>5$dd96<=iml0?76g<1;29 ``=:01eih4:;:k04?6=,ll1>45aed85?>o5n3:1(hh5289ma`<032c9i7>5$dd96<=iml0376g=d;29 ``=:01eih46;:k1g?6=,ll1>45aed8b?>o5j3:1(hh5289ma`5$dd96<=iml0h76go3:3:1(hh5409ma`<732c?<7>5$dd904=iml0:76a;5;29 ``=<=1eih4?;:m77?6=,ll1895aed82?>i303:1(hh5469ma`<732e?:7>5$dd902=iml0:76smfc83>7g=83:p(k95f19K544<@8:27W=9:7y4>="a<3;0(9j52:&7a?4<,=l1>6*:0;08 07=:2.>>7<4$4196>"2<380(8;52:&62?4<,<=1>6*:8;08 0?=:2.>m7<4$4`96>"2k380(8j52:&6a?4<,6*90;08 37=:2.=>7<4$7196>"1<380(;;52:&52?4<,?=1>6*98;08 3?=:2.=m7<4$7`96>"1k380(;j52:&5a?4<,?l1>6*80;08 27=:2.<>7<4$6196>"0<380(:;52:&42?4<,>=1>6*88;08 2?=:2."0k380(:j52:&4a?4<,>l1>6*70;08 =7=:2.3>7<4$9196>"?<380(5;52:&;2?4<,1=1>6*78;08 =?=:2.3m7<4$033>46b3-2i6?5+f0800>"?l3;0(5k51:&24c<68l1/4n4=;h1;>5<>o3i3:17dh::188mc0=831b==m50;9j55b=831b=n4?:%ge>4d!ca28h0bhk51:9j5<<72-om6=n:<0;6)ki:0`8j`c=;21b>94?:%ge>4d!ca28h0bhk55:9j67<72-om6=n:80;6)ki:0`8j`c=?21b>=4?:%ge>4d!ca28h0bhk59:9j5`<72-om6=n9m0;6)ki:0`8j`c=j21b=54?:%ge>4d!ca2;30bhk50:9j6=<72-om6?74ndg95>=n:>0;6)ki:3;8j`c=:21b?>4?:%ge>7?!ca2;30bhk54:9j74<72-om6?74ndg91>=n;90;6)ki:3;8j`c=>21b>k4?:%ge>7?!ca2;30bhk58:9j6a<72-om6?74ndg9=>=n:j0;6)ki:3;8j`c=i21b>o4?:%ge>7?!ca2;30bhk5c:9j7c<72-om6>k4ndg94>=n;m0;6)ki:2g8j`c=921b8?4?:%ge>17!ca2=;0bhk51:9l00<72-om69:4ndg94>=h<:0;6)ki:568j`c=921d854?:%ge>11!ca2==0bhk51:9~fcg=838j6=4?{%d4>c6<@8;97E??9:X02?0|?321o7j5e;d9y!`4281/j94>;%6g>7=#7=#=?097);8:39'1=<53-?26?5+5`81?!3e2;1/9n4=;%7g>7=#=l097);i:39'25<53-<:6?5+6381?!042;1/:94=;%46>7=#>?097)88:39'2=<53-<26?5+6`81?!0e2;1/:n4=;%4g>7=#>l097)8i:39'35<53-=:6?5+7381?!142;1/;94=;%56>7=#??097)98:39'3=<53-=26?5+7`81?!1e2;1/;n4=;%5g>7=#?l097)9i:39'<5<53-2:6?5+8381?!>42;1/494=;%:6>7=#0?097)68:39'<=<53-226?5+8`81?!7683;;i6*7b;08 c7=;=1/4i4>;%:f>4=#99l1==k4$9a96>o403:17d=6:188m1?=831b8l4?::ke1?6=3`l=6=44i02`>5<4=54i3694?"bn3;i7ckj:598m75=83.nj7?m;ogf>0=<=5=3gon6?54i2194?"bn3827ckj:298m64=83.nj7<6;ogf>1=>50;&fb?4>3gon6;54i3d94?"bn3827ckj:698m7c=83.nj7<6;ogf>==3gon6l54i3`94?"bn3827ckj:c98m70=83.nj7<6;ogf>f=j50;&fb?5b3gon6<54i5094?"bn3>:7ckj:198m16=83.nj7:>;ogf>4=<7ckj:198k10=83.nj7:8;ogf>4=2:J24<=];?0=w:47:b8g>`"3l380(9k52:&7b?4<,<:1>6*:1;08 04=:2.>?7<4$4696>"2=380(8852:&63?4<,<21>6*:9;08 0g=:2.>n7<4$4a96>"2l380(8k52:&6b?4<,?:1>6*91;08 34=:2.=?7<4$7696>"1=380(;852:&53?4<,?21>6*99;08 3g=:2.=n7<4$7a96>"1l380(;k52:&5b?4<,>:1>6*81;08 24=:2."0=380(:852:&43?4<,>21>6*89;08 2g=:2."0l380(:k52:&4b?4<,1:1>6*71;08 =4=:2.3?7<4$9696>"?=380(5852:&;3?4<,121>6*79;08 =g=:2.:==4>0d9':4$9f95>"?m3;0(<>i:02f?!>d2;1b?54?::k0=?6=3`>26=44i5c94?=nn<0;66gi6;29?l77k3:17d??d;29?l7d290/ik4>b:lfa?6<3`;j6=4+eg82f>hbm3;07d?6:18'ac<6j2dni7<4;h06>5<#mo0:n6`je;18?l43290/ik4>b:lfa?2<3`886=4+eg82f>hbm3?07d<=:18'ac<6j2dni784;h02>5<#mo0:n6`je;58?l47290/ik4>b:lfa?><3`;m6=4+eg82f>hbm3307d?j:18'ac<6j2dni7o4;h3g>5<#mo0:n6`je;`8?l7?290/ik4>b:lfa?e<3`8j6=4+eg81=>hbm3:07d<7:18'ac<512dni7?4;h04>5<#mo0956`je;08?l54290/ik4=9:lfa?5<3`996=4+eg81=>hbm3>07d=>:18'ac<512dni7;4;h13>5<#mo0956`je;48?l4a290/ik4=9:lfa?1<3`8n6=4+eg81=>hbm3207d5<#mo0956`je;c8?l4e290/ik4=9:lfa?d<3`8=6=4+eg81=>hbm3i07d=i:18'ac<4m2dni7>4;h1g>5<#mo08i6`je;38?l25290/ik4;1:lfa?6<3`>;6=4+eg875>hbm3;07b:::18'ac<3<2dni7>4;n60>5<#mo0?86`je;38?j2?290/ik4;7:lfa?6<3f>=6=4+eg873>hbm3;07pl>0683>7g=83:p(k95f19K544<@8:27W=9:7y4>="a<3;0(9j52:&7a?4<,=l1>6*:0;08 07=:2.>>7<4$4196>"2<380(8;52:&62?4<,<=1>6*:8;08 0?=:2.>m7<4$4`96>"2k380(8j52:&6a?4<,6*90;08 37=:2.=>7<4$7196>"1<380(;;52:&52?4<,?=1>6*98;08 3?=:2.=m7<4$7`96>"1k380(;j52:&5a?4<,?l1>6*80;08 27=:2.<>7<4$6196>"0<380(:;52:&42?4<,>=1>6*88;08 2?=:2."0k380(:j52:&4a?4<,>l1>6*70;08 =7=:2.3>7<4$9196>"?<380(5;52:&;2?4<,1=1>6*78;08 =?=:2.3m7<4$033>46b3-2i6?5+f0800>"?l3;0(5k51:&24c<68l1/4n4=;h1;>5<>o3i3:17dh::188mc0=831b==m50;9j55b=831b=n4?:%ge>4d!ca28h0bhk51:9j5<<72-om6=n:<0;6)ki:0`8j`c=;21b>94?:%ge>4d!ca28h0bhk55:9j67<72-om6=n:80;6)ki:0`8j`c=?21b>=4?:%ge>4d!ca28h0bhk59:9j5`<72-om6=n9m0;6)ki:0`8j`c=j21b=54?:%ge>4d!ca2;30bhk50:9j6=<72-om6?74ndg95>=n:>0;6)ki:3;8j`c=:21b?>4?:%ge>7?!ca2;30bhk54:9j74<72-om6?74ndg91>=n;90;6)ki:3;8j`c=>21b>k4?:%ge>7?!ca2;30bhk58:9j6a<72-om6?74ndg9=>=n:j0;6)ki:3;8j`c=i21b>o4?:%ge>7?!ca2;30bhk5c:9j7c<72-om6>k4ndg94>=n;m0;6)ki:2g8j`c=921b8?4?:%ge>17!ca2=;0bhk51:9l00<72-om69:4ndg94>=h<:0;6)ki:568j`c=921d854?:%ge>11!ca2==0bhk51:9~f4612909m7>50z&e3?`73A;:>6F>089Y73<1s>036n4k:d8e>x"a;3;0(k:51:&7`?4<,=o1>6*;f;08 06=:2.>=7<4$4096>"2;380(8:52:&61?4<,<<1>6*:7;08 0>=:2.>57<4$4c96>"2j380(8m52:&6`?4<,6*:f;08 36=:2.==7<4$7096>"1;380(;:52:&51?4<,?<1>6*97;08 3>=:2.=57<4$7c96>"1j380(;m52:&5`?4<,?o1>6*9f;08 26=:2.<=7<4$6096>"0;380(::52:&41?4<,><1>6*87;08 2>=:2.<57<4$6c96>"0j380(:m52:&4`?4<,>o1>6*8f;08 =6=:2.3=7<4$9096>"?;380(5:52:&;1?4<,1<1>6*77;08 =>=:2.357<4$9c96>"6990:0(5j51:&;a?7<,8:m6<>j;%:`>7=n;10;66g<9;29?l2>2900e9o50;9jb0<722cm:7>5;h33g?6=3`;;h7>5;h3`>5<#mo0:n6`je;28?l7f290/ik4>b:lfa?7<3`;26=4+eg82f>hbm3807d<::18'ac<6j2dni7=4;h07>5<#mo0:n6`je;68?l44290/ik4>b:lfa?3<3`896=4+eg82f>hbm3<07d<>:18'ac<6j2dni794;h03>5<#mo0:n6`je;:8?l7a290/ik4>b:lfa??<3`;n6=4+eg82f>hbm3k07d?k:18'ac<6j2dni7l4;h3;>5<#mo0:n6`je;a8?l4f290/ik4=9:lfa?6<3`836=4+eg81=>hbm3;07d<8:18'ac<512dni7<4;h10>5<#mo0956`je;18?l55290/ik4=9:lfa?2<3`9:6=4+eg81=>hbm3?07d=?:18'ac<512dni784;h0e>5<#mo0956`je;58?l4b290/ik4=9:lfa?><3`8o6=4+eg81=>hbm3307d5<#mo0956`je;`8?l41290/ik4=9:lfa?e<3`9m6=4+eg80a>hbm3:07d=k:18'ac<4m2dni7?4;h61>5<#mo0?=6`je;28?l27290/ik4;1:lfa?7<3f>>6=4+eg870>hbm3:07b:<:18'ac<3<2dni7?4;n6;>5<#mo0?;6`je;28?j21290/ik4;7:lfa?7<3th:<84?:3c94?6|,o=1j=5G1008L46>3S9=6;u8:98`>a6*;e;08 1`=:2.><7<4$4396>"2:380(8=52:&60?4<,6*:6;08 01=:2.>47<4$4;96>"2i380(8l52:&6g?4<,6*:e;08 0`=:2.=<7<4$7396>"1:380(;=52:&50?4<,??1>6*96;08 31=:2.=47<4$7;96>"1i380(;l52:&5g?4<,?n1>6*9e;08 3`=:2.<<7<4$6396>"0:380(:=52:&40?4<,>?1>6*86;08 21=:2.<47<4$6;96>"0i380(:l52:&4g?4<,>n1>6*8e;08 2`=:2.3<7<4$9396>"?:380(5=52:&;0?4<,1?1>6*76;08 =1=:2.347<4$9;96>"?i380(e2;1/j<4<4:&;`?7<,1o1=6*>0g824`=#0j097d=7:188m6?=831b844?::k7e?6=3`l>6=44ig494?=n99i1<75f11f94?=n9j0;6)ki:0`8j`c=821b=l4?:%ge>4d!ca28h0bhk52:9j60<72-om6=n:=0;6)ki:0`8j`c=<21b>>4?:%ge>4d!ca28h0bhk56:9j64<72-om6=n:90;6)ki:0`8j`c=021b=k4?:%ge>4d!ca28h0bhk5a:9j5a<72-om6=n910;6)ki:0`8j`c=k21b>l4?:%ge>7?!ca2;30bhk51:9j62<72-om6?74ndg96>=n;:0;6)ki:3;8j`c=;21b??4?:%ge>7?!ca2;30bhk55:9j75<72-om6?74ndg92>=n:o0;6)ki:3;8j`c=?21b>h4?:%ge>7?!ca2;30bhk59:9j6f<72-om6?74ndg9e>=n:k0;6)ki:3;8j`c=j21b>;4?:%ge>7?!ca2:o0bhk50:9j7a<72-om6>k4ndg95>=n<;0;6)ki:538j`c=821b8=4?:%ge>17!ca2=>0bhk50:9l06<72-om69:4ndg95>=h<10;6)ki:558j`c=821d8;4?:%ge>115<5i3:11=6*;d;08 1c=:2.?j7<4$4296>"29380(8<52:&67?4<,<>1>6*:5;08 00=:2.>;7<4$4:96>"21380(8o52:&6f?4<,6*:d;08 0c=:2.>j7<4$7296>"19380(;<52:&57?4<,?>1>6*95;08 30=:2.=;7<4$7:96>"11380(;o52:&5f?4<,?i1>6*9d;08 3c=:2.=j7<4$6296>"09380(:<52:&47?4<,>>1>6*85;08 20=:2.<;7<4$6:96>"01380(:o52:&4f?4<,>i1>6*8d;08 2c=:2."?9380(5<52:&;7?4<,1>1>6*75;08 =0=:2.3;7<4$9:96>"?1380(5o52:&255<68l1/4o4=;%d2>62<,1n1=6*7e;38 46a28:n7)6l:39j7=<722c857>5;h6:>5<>oa>3:17d??c;29?l77l3:17d?l:18'ac<6j2dni7>4;h3b>5<#mo0:n6`je;38?l7>290/ik4>b:lfa?4<3`8>6=4+eg82f>hbm3907d<;:18'ac<6j2dni7:4;h00>5<#mo0:n6`je;78?l45290/ik4>b:lfa?0<3`8:6=4+eg82f>hbm3=07d5<#mo0:n6`je;;8?l7b290/ik4>b:lfa?g<3`;o6=4+eg82f>hbm3h07d?7:18'ac<6j2dni7m4;h0b>5<#mo0956`je;28?l4?290/ik4=9:lfa?7<3`8<6=4+eg81=>hbm3807d=<:18'ac<512dni7=4;h11>5<#mo0956`je;68?l56290/ik4=9:lfa?3<3`9;6=4+eg81=>hbm3<07d5<#mo0956`je;:8?l4c290/ik4=9:lfa??<3`8h6=4+eg81=>hbm3k07d5<#mo0956`je;a8?l5a290/ik4hbm3;07d:=:18'ac<392dni7>4;h63>5<#mo0?=6`je;38?j22290/ik4;4:lfa?6<3f>86=4+eg870>hbm3;07b:7:18'ac<3?2dni7>4;n65>5<#mo0?;6`je;38?xd68:0;6?o50;2x c1=n91C=<<4H02:?_512?q<654l:e8f>c"28380(8?52:&66?4<,<91>6*:4;08 03=:2.>:7<4$4596>"20380(8752:&6e?4<,

6*:c;08 0b=:2.>i7<4$4d96>"18380(;?52:&56?4<,?91>6*94;08 33=:2.=:7<4$7596>"10380(;752:&5e?4<,?h1>6*9c;08 3b=:2.=i7<4$7d96>"08380(:?52:&46?4<,>91>6*84;08 23=:2.<:7<4$6596>"00380(:752:&4e?4<,>h1>6*8c;08 2b=:2."?8380(5?52:&;6?4<,191>6*74;08 =3=:2.3:7<4$9596>"?0380(5752:&;e?4<,8;;6<>j;%:a>7=#n80886*7d;38 =c=92.:0d9'=n9h0;6)ki:0`8j`c=921b=44?:%ge>4d65f2483>!ca28h0bhk53:9j61<72-om6=n::0;6)ki:0`8j`c==21b>?4?:%ge>4d!ca28h0bhk57:9j65<72-om6=n9o0;6)ki:0`8j`c=121b=h4?:%ge>4d!ca28h0bhk5b:9j5=<72-om6=n:h0;6)ki:3;8j`c=821b>54?:%ge>7?!ca2;30bhk52:9j76<72-om6?74ndg97>=n;;0;6)ki:3;8j`c=<21b?<4?:%ge>7?!ca2;30bhk56:9j6c<72-om6?74ndg93>=n:l0;6)ki:3;8j`c=021b>i4?:%ge>7?!ca2;30bhk5a:9j6g<72-om6?74ndg9f>=n:?0;6)ki:3;8j`c=k21b?k4?:%ge>6c!ca2:o0bhk51:9j07<72-om69?4ndg94>=n<90;6)ki:538j`c=921d884?:%ge>12!ca2=>0bhk51:9l0=<72-om6994ndg94>=h=:181e?6=8r.m;7h?;I326>N6801Q?;49{68;>f"3n380(8>52:&65?4<,<81>6*:3;08 02=:2.>97<4$4496>"2?380(8652:&6=?4<,6*:b;08 0e=:2.>h7<4$4g96>"2n380(;>52:&55?4<,?81>6*93;08 32=:2.=97<4$7496>"1?380(;652:&5=?4<,?k1>6*9b;08 3e=:2.=h7<4$7g96>"1n380(:>52:&45?4<,>81>6*83;08 22=:2.<97<4$6496>"0?380(:652:&4=?4<,>k1>6*8b;08 2e=:2."0n380(5>52:&;5?4<,181>6*73;08 =2=:2.397<4$9496>"??380(5652:&;=?4<,1k1>6*>11824`=#0k097)h>:268 =b=92.3i7?4$02e>46b3-2h6?5f3983>>o413:17d:6:188m1g=831bj84?::ke2?6=3`;;o7>5;h33`?6=3`;h6=4+eg82f>hbm3:07d?n:18'ac<6j2dni7?4;h3:>5<#mo0:n6`je;08?l42290/ik4>b:lfa?5<3`8?6=4+eg82f>hbm3>07d<<:18'ac<6j2dni7;4;h01>5<#mo0:n6`je;48?l46290/ik4>b:lfa?1<3`8;6=4+eg82f>hbm3207d?i:18'ac<6j2dni774;h3f>5<#mo0:n6`je;c8?l7c290/ik4>b:lfa?d<3`;36=4+eg82f>hbm3i07d4;h0;>5<#mo0956`je;38?l40290/ik4=9:lfa?4<3`986=4+eg81=>hbm3907d==:18'ac<512dni7:4;h12>5<#mo0956`je;78?l57290/ik4=9:lfa?0<3`8m6=4+eg81=>hbm3=07d5<#mo0956`je;;8?l4d290/ik4=9:lfa?g<3`8i6=4+eg81=>hbm3h07d<9:18'ac<512dni7m4;h1e>5<#mo08i6`je;28?l5c290/ik496=4+eg875>hbm3:07d:?:18'ac<392dni7?4;n66>5<#mo0?86`je;28?j24290/ik4;4:lfa?7<3f>36=4+eg873>hbm3:07b:9:18'ac<3?2dni7?4;|`244<72;k1<7>t$g59b5=O9880D<>6;[15>3}0210h6i4j:g8~ c5=92.m87?4$5f96>"3m380(9h52:&64?4<,<;1>6*:2;08 05=:2.>87<4$4796>"2>380(8952:&66*:a;08 0d=:2.>o7<4$4f96>"2m380(8h52:&54?4<,?;1>6*92;08 35=:2.=87<4$7796>"1>380(;952:&56*9a;08 3d=:2.=o7<4$7f96>"1m380(;h52:&44?4<,>;1>6*82;08 25=:2.<87<4$6796>"0>380(:952:&431>6*8a;08 2d=:2."0m380(:h52:&;4?4<,1;1>6*72;08 =5=:2.387<4$9796>"?>380(5952:&;6*7a;08 47728:n7)6m:39'b4<4<2.3h7?4$9g95>"68o0:750;9j0<<722c?m7>5;hd6>5<!ca28h0bhk50:9j5d<72-om6=n900;6)ki:0`8j`c=:21b>84?:%ge>4d!ca28h0bhk54:9j66<72-om6=n:;0;6)ki:0`8j`c=>21b><4?:%ge>4d!ca28h0bhk58:9j5c<72-om6=n9l0;6)ki:0`8j`c=i21b=i4?:%ge>4d!ca28h0bhk5c:9j6d<72-om6?74ndg94>=n:10;6)ki:3;8j`c=921b>:4?:%ge>7?65f3283>!ca2;30bhk53:9j77<72-om6?74ndg90>=n;80;6)ki:3;8j`c==21b?=4?:%ge>7?!ca2;30bhk57:9j6`<72-om6?74ndg9<>=n:m0;6)ki:3;8j`c=121b>n4?:%ge>7?!ca2;30bhk5b:9j63<72-om6?74ndg9g>=n;o0;6)ki:2g8j`c=821b?i4?:%ge>6c!ca2=;0bhk50:9j05<72-om69?4ndg95>=h<<0;6)ki:568j`c=821d8>4?:%ge>12!ca2==0bhk50:9l03<72-om6994ndg95>=zj8:;6=4=a;294~"a?3l;7E?>2:J24<=];?0=w:47:b8g>`"3l380(9k52:&7b?4<,<:1>6*:1;08 04=:2.>?7<4$4696>"2=380(8852:&63?4<,<21>6*:9;08 0g=:2.>n7<4$4a96>"2l380(8k52:&6b?4<,?:1>6*91;08 34=:2.=?7<4$7696>"1=380(;852:&53?4<,?21>6*99;08 3g=:2.=n7<4$7a96>"1l380(;k52:&5b?4<,>:1>6*81;08 24=:2."0=380(:852:&43?4<,>21>6*89;08 2g=:2."0l380(:k52:&4b?4<,1:1>6*71;08 =4=:2.3?7<4$9696>"?=380(5852:&;3?4<,121>6*79;08 =g=:2.:==4>0d9':4$9f95>"?m3;0(<>i:02f?!>d2;1b?54?::k0=?6=3`>26=44i5c94?=nn<0;66gi6;29?l77k3:17d??d;29?l7d290/ik4>b:lfa?6<3`;j6=4+eg82f>hbm3;07d?6:18'ac<6j2dni7<4;h06>5<#mo0:n6`je;18?l43290/ik4>b:lfa?2<3`886=4+eg82f>hbm3?07d<=:18'ac<6j2dni784;h02>5<#mo0:n6`je;58?l47290/ik4>b:lfa?><3`;m6=4+eg82f>hbm3307d?j:18'ac<6j2dni7o4;h3g>5<#mo0:n6`je;`8?l7?290/ik4>b:lfa?e<3`8j6=4+eg81=>hbm3:07d<7:18'ac<512dni7?4;h04>5<#mo0956`je;08?l54290/ik4=9:lfa?5<3`996=4+eg81=>hbm3>07d=>:18'ac<512dni7;4;h13>5<#mo0956`je;48?l4a290/ik4=9:lfa?1<3`8n6=4+eg81=>hbm3207d5<#mo0956`je;c8?l4e290/ik4=9:lfa?d<3`8=6=4+eg81=>hbm3i07d=i:18'ac<4m2dni7>4;h1g>5<#mo08i6`je;38?l25290/ik4;1:lfa?6<3`>;6=4+eg875>hbm3;07b:::18'ac<3<2dni7>4;n60>5<#mo0?86`je;38?j2?290/ik4;7:lfa?6<3f>=6=4+eg873>hbm3;07plif;296d<729q/j:4i0:J257=O9930V>856z597=#7=#=>097);7:39'1<<53-?j6?5+5c81?!3d2;1/9i4=;%7f>7=#=o097)8?:39'24<53-<96?5+6281?!032;1/:84=;%45>7=#>>097)87:39'2<<53-7=#>o097)9?:39'34<53-=96?5+7281?!132;1/;84=;%55>7=#?>097)97:39'3<<53-=j6?5+7c81?!1d2;1/;i4=;%5f>7=#?o097)6?:39'<4<53-296?5+8281?!>32;1/484=;%:5>7=#0>097)67:39'<<<53-2j6?5+102955c<,1h1>6*i1;17?!>c281/4h4>;%33b?77m2.3o7<4i2:94?=n;00;66g;9;29?l2f2900ek;50;9jb3<722c:5$dd95g=iml0;76g>a;29 ``=9k1eih4>;:k2=?6=,ll1=o5aed81?>o5=3:1(hh51c9ma`<432c987>5$dd95g=iml0?76g=3;29 ``=9k1eih4:;:k16?6=,ll1=o5aed85?>o593:1(hh51c9ma`<032c9<7>5$dd95g=iml0376g>f;29 ``=9k1eih46;:k2a?6=,ll1=o5aed8b?>o6l3:1(hh51c9ma`5$dd95g=iml0h76g=a;29 ``=:01eih4?;:k145aed82?>o5?3:1(hh5289ma`<532c8?7>5$dd96<=iml0876g<2;29 ``=:01eih4;;:k05?6=,ll1>45aed86?>o483:1(hh5289ma`<132c9j7>5$dd96<=iml0<76g=e;29 ``=:01eih47;:k1`?6=,ll1>45aed8:?>o5k3:1(hh5289ma`5$dd96<=iml0i76g=6;29 ``=:01eih4l;:k0b?6=,ll1?h5aed83?>o4l3:1(hh53d9ma`<632c?>7>5$dd904=iml0;76g;0;29 ``=<81eih4>;:m71?6=,ll1895aed83?>i3;3:1(hh5459ma`<632e?47>5$dd902=iml0;76a;6;29 ``=<>1eih4>;:ab=<72;k1<7>t$g59b5=O9880D<>6;[15>3}0210h6i4j:g8~ c5=92.m87?4$5f950=#1/9<4<;%71>7=#=:097);;:39'10<53-?=6?5+5681?!3?2;1/944=;%7b>7=#=k097);l:39'1a<53-?n6?5+5g81?!072;1/:<4=;%41>7=#>:097)8;:39'20<53-<=6?5+6681?!0?2;1/:44=;%4b>7=#>k097)8l:39'2a<53-7=#?:097)9;:39'30<53-==6?5+7681?!1?2;1/;44=;%5b>7=#?k097)9l:39'3a<53-=n6?5+7g81?!>72;1/4<4=;%:1>7=#0:097)6;:39'<0<53-2=6?5+8681?!>?2;1/444=;%:b>7=#98:1==k4$9`96>"a939?7)6k:09'<`<63-;;j7??e:&;g?4>o313:17d:n:188mc3=831bj;4?::k24f<722c:o6i3:1(hh51c9ma`<632c:57>5$dd95g=iml0976g=5;29 ``=9k1eih4<;:k10?6=,ll1=o5aed87?>o5;3:1(hh51c9ma`<232c9>7>5$dd95g=iml0=76g=1;29 ``=9k1eih48;:k14?6=,ll1=o5aed8;?>o6n3:1(hh51c9ma`<>32c:i7>5$dd95g=iml0j76g>d;29 ``=9k1eih4m;:k2o5i3:1(hh5289ma`<732c947>5$dd96<=iml0:76g=7;29 ``=:01eih4=;:k07?6=,ll1>45aed80?>o4:3:1(hh5289ma`<332c8=7>5$dd96<=iml0>76g<0;29 ``=:01eih49;:k1b?6=,ll1>45aed84?>o5m3:1(hh5289ma`5$dd96<=iml0276g=c;29 ``=:01eih4n;:k1f?6=,ll1>45aed8a?>o5>3:1(hh5289ma`5$dd97`=iml0;76g;:k76?6=,ll18<5aed83?>o383:1(hh5409ma`<632e?97>5$dd901=iml0;76a;3;29 ``=<=1eih4>;:m7i3>3:1(hh5469ma`<632wx=9850;32[73>27mi7=7;6><5oi1?552fc80<>;ai39370h6:2:894602:201<>9:2:894622:201<>;:2:894642:201<>=:2:894662:201<>?:2:89c`=;116j54<8:p511=83;:wS?;7:?ea?5>34lo6>74=ga97<=:nk08563ia;1:?8`>2:301<>8:2;894612:301<>::2;894632:301<><:2;894652:301<>>:2;894672:301kh5389>b=<412wx=n850;f2[7en2T:ni5Q1ca8Z4de3W;im6P>b89]5g>0RX6j91U=lh4^0cf?[7fl2T:mn5Q1``8Z4gf3W;j56P>c49]5f2X6i11U=l94=030>1d<5oo1j852fd8e2>;am3;;h63ie;3`?8`b28k01kk5189>b`<5i27mi7<7;71<5oo1?k52fd876>;am3>;70hk:g789cb=n?16ji4>0e9>ba<6k27mh7?n;4?<5on1>l52fe81<>;al38<70hk:5089cb=<916jn4i5:?eg?`134lh6<>k;4e<5oi1=l52fb82=>;ak38j70hl:3:89ce=:>16jn4;2:?eg?2734li6k;4=g`9b3=:nk0:;aj3;j70hm:0;89cd=:h16jo4=8:?ef?4034li69<4=g`905=:nh0m963ia;d5?8`f28:o70hn:0a89cg=9h16jl4>9:?ee?4f34lj6?64=gc962=:nh0?>63ia;63?8`>2o?01k75f79>b<<68m16j44>c:?e=?7f34l26<74=g;96d=:n009463i9;04?8`>2=801k75419>551=n<16==95f79>551=99n01<>8:0a8946028k01<>8:0;894602;k01<>8:3:894602;=01<>8:50894602=:01<>9:g7894612o<01<>9:02g?877>3;h70??6;3b?877>3;270??6;0b?877>38370??6;04?877>3>970??6;63?877=3l>70??5;d5?877=3;;h63>0482g>;68<0:m63>0482=>;68<09m63>0481<>;68<09;63>04876>;68<0?<63>058e1>;68=0m:63>05824a=:99>1=n5211695d=:99>1=45211696d=:99>1>552116962=:99>18?52116905=:9991j8521119b3=:9991==j4=020>4e<58:864?<58:86?o4=020>7><58:86?94=020>14<58:869>4=021>c3<58:96k84=021>46c34;;>7?l;<336?7f34;;>7?6;<336?4f34;;>7<7;<336?4034;;>7:=;<336?2734;;=7h:;<335?`134;;=7??d:?244<6k27:<<4>a:?244<6127:<<4=a:?244<5027:<<4=7:?244<3:27:<<4;0:?24551b9>556=9h16==>5189>556=:h16==>5299>556=:>16==>5439>556=<916jk4i5:?eb?`134lm6<>k;4e<5ol1=l52fg82=>;an38j70hi:3:89c`=:>16jk4;2:?eb?2734l36k;4=g:9b3=:n10:;a03;j70h7:0;89c>=:h16j54=8:?e;am3>=7p}>fb83>7}Y9mo01kj5499~w4`e2909wS?kd:?e`?213ty:jl4?:3y]5ae<5oi1855rs0d:>5<5sW;on63ic;65?xu6n10;6?uQ1ec89cd=<11v6=4={_3g3>;ai3>=7p}>f583>7}Y9m<01k75499~w4`42909wS?k5:?e=?213ty:j<4?:3y]5a5<58:<6964}r3e4?6=:rT:h?52115903=z{8om6=4={_3g5>;68?0?46s|1dg94?4|V8n;70??6;65?xu6mm0;6?uQ1bd894622=20q~?jc;296~X6kl16==;5479~w4ce2909wS?ld:?241<302wx=ho50;0xZ4ed34;;87:9;|q2a<<72;qU=nl4=020>1>52z\2gd=:99918;5rs325>5<5sW;n:63>0387<>{t:9?1<7=7p}=0583>7}Y9l>01<>>:5:8yv47;3:1>vP>e29>557==:181[7b:27:<=4;8:p657=838pR;<334?213ty9<=4?:3y]5a`<5ol1855rs0dg>5<5sW;o863if;65?xu6n;0;6?uQ1b;89c>=<11v46d34lo6<>l;46d34li6<>l;46d34l26<>l;<333?77k27:<;4>0b9>553=99i01<>;:02`?877;3;;o63>03824f=:99;1==m4=023>46d34lm6<>l;46d3ty:>h4?:03xZ44434ln6?;4=gf960=:nj09963ib;06?8`f2;?01k75249>551=:<16==85249>553=:<16==:5249>555=:<16==<5249>557=:<16==>5249>bc<5=27m47<:;|q26f<728;pR<<=;72<5on1>952fb810>;aj38?70hn:3689c?=:=16==95259>550=:=16==;5259>552=:=16===5259>554=:=16==?5259>556=:=16jk4=4:?eo4?:03xZ44634ln6?=4=gf966=:nj09?63ib;00?8`f2;901k75229>551=::16==85229>553=::16==:5229>555=::16==<5229>557=::16==>5229>bc<5;27m47<<;|q26d<728;pR<74<5on1>?52fb816>;aj38970hn:3089c?=:;16==95239>550=:;16==;5239>552=:;16===5239>554=:;16==?5239>556=:;16jk4=2:?e44?:03xZ47a34ln6??4=gf964=:nj09=63ib;02?8`f2;;01k75209>551=:816==85209>553=:816==:5209>555=:816==<5209>557=:816==>5209>bc<5927m47<>;|q26=<728;pR76<5on1>=52fb814>;aj38;70hn:3289c?=:916==95219>550=:916==;5219>552=:916===5219>554=:916==?5219>556=:916jk4=0:?e:4?:03xZ47c34ln6551=9o16==851g9>553=9o16==:51g9>555=9o16==<51g9>557=9o16==>51g9>bc<6n27m47?i;|q263<728;pR4c<5on1=h52fb82a>;aj3;n70hn:0g89c?=9l16==951d9>550=9l16==;51d9>552=9l16===51d9>554=9l16==?51d9>556=9l16jk4>e:?e84?:03xZ47e34ln6551=9m16==851e9>553=9m16==:51e9>555=9m16==<51e9>557=9m16==>51e9>bc<6l27m47?k;|q261<728;pR4><5on1=552fb82<>;aj3;370hn:0:89c?=9116==95199>550=9116==;5199>552=9116===5199>554=9116==?5199>556=9116jk4>8:?e4?:03xZ45?34ln6>=4=gf976=:nj08?63ib;10?8`f2:901k75329>551=;:16==85329>553=;:16==:5329>555=;:16==<5329>557=;:16==>5329>bc<4;27m47=<;|q204<728;pR<=8;64<5on1??52fb806>;aj39970hn:2089c?=;;16==95339>550=;;16==;5339>552=;;16===5339>554=;;16==?5339>556=;;16jk4<2:?e?4=gf974=:nj08=63ib;12?8`f2:;01k75309>551=;816==85309>553=;816==:5309>555=;816==<5309>557=;816==>5309>bc<4927m47=>;|q27c<728;pR<=:;66<5on1?=52fb804>;aj39;70hn:2289c?=;916==95319>550=;916==;5319>552=;916===5319>554=;916==?5319>556=;916jk4<0:?e551=:o16==852g9>553=:o16==:52g9>555=:o16==<52g9>557=:o16==>52g9>bc<5n27m477c<5on1>h52fb81a>;aj38n70hn:3g89c?=:l16==952d9>550=:l16==;52d9>552=:l16===52d9>554=:l16==?52d9>556=:l16jk4=e:?e551=:m16==852e9>553=:m16==:52e9>555=:m16==<52e9>557=:m16==>52e9>bc<5l27m47;7e<5on1>n52fb81g>;aj38h70hn:3a89c?=:j16==952b9>550=:j16==;52b9>552=:j16===52b9>554=:j16==?52b9>556=:j16jk4=c:?e551=:k16==852c9>553=:k16==:52c9>555=:k16==<52c9>557=:k16==>52c9>bc<5j27m4770<5on1>;52fb812>;aj38=70hn:3489c?=:?16==95279>550=:?16==;5279>552=:?16===5279>554=:?16==?5279>556=:?16jk4=6:?e5<5sW;>i63id;1e?xu6?k0;6?uQ14f89cb=;m1v<9n:181[72k27mo7=i;|q23<<72;qU=8l4=ga97a=z{8=36=4={_36e>;aj39m7p}>7683>7}Y9<301kl53e9~w4112909wS?:8:?ee?5a3ty:;84?:3y]501<5ok1?i5rs057>5<5sW;>:63i9;1e?xu6?:0;6?uQ14789c?=;m1v<9>:181[72;27:<:4h4}r35a?6=:rT:9=5211497a=z{8;68<08j6s|17a94?4|V8>n70??5;1g?xu6>k0;6?uQ15f894632:l0q~?9a;296~X62909wS?;b:?246<4n2wx=;650;0xZ42f34;;?7=k;|q2<3<72;qU=;84=021>6`52z\220=:9981?i5rs0:7>5<5sW;=863>0080b>{t9191<78383>7}Y9?801<>?:2d8yv7?93:1>vP>609>556=;m1v<6?:181[72n27mj7=i;|q23a<72;qU=8:4=gd97a=z{8=96=4={_37=>;a039m7p}>6683>7}Y9=201k653e9~w<5=838:w0?>4;g`?8`b2=301kk54`9>ba<3127mh7:n;1?<5oi18l52fc87=>;aj3>j70hn:5;89cg=7:6;<336?2f34;;=7:6;<335?2f34;;<7:6;<334?2f34lm6974=gd90d=:n10?563i8;6b?x{t9=<1<7=7)??8;a4?xu6?o0;6?uQ1728963=9?:0(<>7:e08yv70k3:1>vP>5d9>70<6=l1/==65de9~w41e2909wS?:d:?01?72l2.:<54j3:p52g=838pR<;l;<16>43d3-;;47k;;|q23<<72;qU=8l4=27950d<,8:36h;4}r345<5sW;>563<5;36=>"6810n46s|16494?4|V8?370=::07;?!77033?7p}>7483>7}Y9<=01>;51458 46?20?0q~?84;296~X6=?16?84>579'55>=1o1v<9<:181[72=27897?:5:&24=2wx=:?50;0xZ434349>6<;<;%33ge52z\214=:;<0:9<5+11:9g6=z{8;4=3;><6*>098`0>{t9?n1<7m7)??8;a6?xu6>j0;6?uQ15g8963=9=o0(<>7:b48yv71j3:1>vP>4e9>70<642e3-;;47mn;|q22=<72;qU=9o4=27951g<,8:36nl4}r3;2?6=:rT::;52348223=#9921on5rs0:6>5<5sW;=963<5;351>"6810hh6s|19694?4|V88283>7}Y9?901>;51718 46?2jl0q~?72;296~X6>;16?84>639'55>=l91v<6>:181[71927897?91:&24=50;0xZ43a349>6<;i;%33a27>52z\20<=:;<0:845+11:9`0=z{8<<6=4={_37<>;4=3;?46*>098g2>{t9;o1<77:e:8yv75j3:1>vP>209>70<6:81/==65d89~w44f2909wS?=0:?01?7582.:<54ka:p57?=838pR47a3-;;47jm;|q26=<72;qU=5<5sW;:o63<5;32g>"6810oj6s|13794?4|V8;i70=::03a?!7703o;7p}>2583>7}Y98k01>;510c8 46?2l;0q~<>5;296~X59:16?84=129'55>=m;1v<:8:181[73?27897?;7:&24=2wx=9=50;0xZ45?349>6<=7;%3394$02;><152z\273=:;<0:?;5+11:9===z{89m6=4={_301>;4=3;896*>098:=>{t9:o1<77:8`8yv74k3:1>vP>339>70<6;;1/==659b9~w45e2909wS?<1:?01?7492.:<546d:p56g=838pR<=?;<16>4573-;;477j;|q27<<72;qU=?h4=27957`<,8:36l>4}r3eb?6=:rT:i=523482a5=#9921m<5rs0d`>5<5sW;oi63<5;3ga>"6810j>6s|1g`94?4|V8no70=::0fg?!7703k87p}>f`83>7}Y9mi01>;51ea8 46?2h>0q~?i9;296~X6lk16?84>dc9'55>=i<1v349>6<5:?1=i64$02;>d?52z\2`2=:;<0:h:5+11:9ed=z{8l?6=4={_3g2>;4=3;o:6*>098bf>{t9o91<77)??8;c`?xu6n80;6?uQ1e18963=9m90(<>7:`f8yv7a83:1>vP>d39>70<6l;1/==65ad9~w4ca2909wS?k1:?01?7c92.:<54nf:p5`c=838pR4b73-;;47l?;|q2aa<72;qU=nh4=2795f`<,8:36o<4}r3fg?6=:rT:oh523482g`=#9921n>5rs0ga>5<5sW;hh63<5;3``>"6810i86s|1dc94?4|V8ih70=::0a`?!7703h>7p}>e883>7}Y9jh01>;51b`8 46?2k<0q~?j8;296~X6kh16?84>c`9'55>=j>1v?>9:181[7b>27897?j6:&24==;50;0xZ4c2349>63ty9<94?:3y]5`2<5:?1=h:4$02;>gg52z\2a6=:;<0:i>5+11:9fg=z{;:96=4={_3f6>;4=3;n>6*>098a`>{t:9;1<77:cd8yv7al3:1>vP>d59>70<6l=1/==65c19~w4`52909wS?l9:?01?7d12.:<54l1:p5`1=838pR4e?3-;;47m=;|m05g=838pD<>6;|l74g<72;qC==74}o63g?6=:rB:<45rn52g>5<5sA;;56sa41g94?4|@8:27p`;0g83>7}O9930qc:>0;296~N6801vb9?>:181M7712we8<<50;0xL46>3td?=>4?:3yK55?:87>52zJ24<=zf=;>6=4={I33=>{i<8<1<70;6?uG11;8yk2603:1>vF>089~j17>2909wE??9:m04g=838pD<>6;|l75g<72;qC==74}o62g?6=:rB:<45rn53g>5<5sA;;56sa40g94?4|@8:27p`;1g83>7}O9930qc:=0;296~N6801vb9<>:181M7712we8?<50;0xL46>3td?>>4?:3yK55?987>52zJ24<=zf=8>6=4={I33=>{i<;<1<70;6?uG11;8yk2503:1>vF>089~j14>2909wE??9:m07g=838pD<>6;|l76g<72;qC==74}o61g?6=:rB:<45rn50g>5<5sA;;56sa43g94?4|@8:27p`;2g83>7}O9930qc:<0;296~N6801vb9=>:181M7712we8><50;0xL46>3td??>4?:3yK55?887>52zJ24<=zf=9>6=4={I33=>{i<:<1<70;6?uG11;8yk2403:1>vF>089~j15>2909wE??9:m06g=838pD<>6;|l77g<72;qC==74}o60g?6=:rB:<45rn51g>5<5sA;;56sa42g94?4|@8:27p`;3g83>7}O9930qc:;0;296~N6801vb9:>:181M7712we89<50;0xL46>3td?8>4?:3yK55??87>52zJ24<=zf=>>6=4={I33=>{i<=<1<70;6?uG11;8yk2303:1>vF>089~j12>2909wE??9:m01g=838pD<>6;|l70g<72;qC==74}o67g?6=:rB:<45rn56g>5<5sA;;56sa45g94?4|@8:27p`;4g83>7}O9930qc::0;296~N6801vb9;>:181M7712we88<50;0xL46>3td?9>4?:3yK55?>87>52zJ24<=zf=?>6=4={I33=>{i<<<1<70;6?uG11;8yk2203:1>vF>089~j13>2909wE??9:m00g=838pD<>6;|l71g<72;qC==74}o66g?6=:rB:<45rn57g>5<5sA;;56sa44g94?4|@8:27p`4}O9930qc:?9;295~N6801vqpsO@By7f3<5kknhmksO@Cy3yEFWstJK \ No newline at end of file diff --git a/Examples/ehw4/logic/dpram624x31.ngc b/Examples/ehw4/logic/dpram624x31.ngc new file mode 100644 index 0000000..10269d0 --- /dev/null +++ b/Examples/ehw4/logic/dpram624x31.ngc @@ -0,0 +1,3 @@ +XILINX-XDB 0.1 STUB 0.1 ASCII +XILINX-XDM V1.4e +$3c44g<,[o}e~g`n;"2*413&;$>"9 > %7845678=:0<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;8=5?01234563<9:><9;>0572546799??==:>1572553388>:9=:>1063056699?>98:;0:23456789K9;8KN=OMCC63?565?9I:;=:I6101G544?9N;4=L7511F35C2993I8=:?A1177506L9>8N=78312BG16<89>3<8J?002G4=1?8J;OK?;I8>?D223=237IL8;H5>?F163F=1700=;:I7?C633=0778LI?<6>?BB2F2=6C1<:;8N>L3022176FKM:3;;>:F92:B763N0:I=L>86022=66CK1::I::?;133656>M99O8=;=71FFF5B6M9O;4=8;B154F545992OJ=86816A251C>9L?4=9NA52844418M9:<8JI0@0G45>E819I<<9M0D2@4AEB8JOO<:O?09AF05=79>H;?99?DEF37K;9>K?5B;336C7I8L;I=H?F9:36@6382::I<>86027=G60>8:OM:>JAG20E46709:?J=>J8821F=65>=:OOK>=972E7<6F:0>;7=AL9:O4=;76126555E?9I2;=7I91673536J98NO=L:01;4G5D3M93H;9>4057G4@?68>L80C7540418H;J<4;>08:E45?78;H<8;?BD:74>629<:M8=>9572F1D6>9K:2HN>NC92G@764?>:M85>;D4231166?::OMN>8F32FF42739?H4=;>61CFG52409:HJ=<711;42504;99>;=88B1;FG5CCN9K;5=O9F1F0G5678=:0<;?I07@:4GE08K8:?0I89L<=F9D1G2>A:9?M<9<;0:25=7658K:J5N>=8724FF6CNJ:O<4>?CD20E467L::N=?>K9B2@=A6D0K:N;H>KA163?50>L93J:=M?11F:F54A=9L9J=7741CBF51A:93O4=67015:5576M988092G@567=8:359>7B7266C65JO:J:H>I5D2E=G6CNK::=;>NEC234@6FNJ:8O9:?;151=5G3K9?CN9<4:802414GBA8>9O<;;?083B42468;8=?C7:3=0G2E1F6A99:M98>K042EA66>1O::;=>7622G<5601?:9N5>=632E4661<9>;7=OM81FA=5D089:8I=ON61A475>BM9NJ===589N??=JLB15515G3:9;2I9>40@@G41708K>=<8:I0E:B4A6>883J<><<0DAG47C388?M4193EF77I?I;:9>?13C3F<77=:=;4N;?6G;34547:O8;I:K?C9C3GCD7?MN;5?;?E4;74>6FKJ::M:><072@1F6DL;:M>8>9A32GBC6CKJ:M4K>?15257@6>=;:OO?>:C622GA2739HI?=J991DB55>019>:>=K:A15;<5@1L9>8I=?I811F7534N9ONI=7804G3445D8L;0:2@3064:8:=N<><2020406DK9:OHL>J4C22>FE2GF56>>J::O:>LFE63?5B2J9N9==;LE1G;G5G5J92>8=J<216:<56709::;==JB1G7G56CM9>8>=>:917F@16<8M=H0@1:4@6C8=:<?F5236AE7819;8OK?DGD3G6>70<8?<6>J662EF56CLO:J84>9F4263363M0:?:;>>F921FA62;1:I<>>JA125G46?=0:==;D15EB5>F89828=H;01@0=534N9=;M81D1@5CA>9I;H=M9A5284C0180KM<>K80C7A4DBE8=:8<;<80BA@4D4E8H2N<=<60@C@4D6D8:>8<>>K0@FF05=7NM3;9?M?4C035?7CD372571M3;I=9?F6A3E@4382:MH4>6462GFD6C19:J?:>;DG21A36F>=:;HK>8C226A76>M8:MH9>>E727406E9090=#>;0:3341379<:>=8??11634062=9:;98::4536456799?>=<:;042350669<;:9<;:4530?46=AGZ^X7OKDSC?=?699:1:<7GAPTV9EABUJ531<3?<;029MKVR\3koho39;2=56=683CE\XZ5aefqf9?=87>;7<:?00330176==>:98>?50261077<=;;8=?>45660132==:?99>:413345228=>?99>41473002698?>98;?54730532<<;?8<;?4473412798?:89??0463446388?;<<::13922?OIX\^1HDO31483:44<9?0BB][[:EKA843=87;87<85OTVSQQ112922?IR\Y__6IAM<0794;2738A>L<:>KLL93D1@F>C:HLSQQ0:39MKVR\3}nn1>50?63?4BE>J2JN?M6D24E2154<;9IJ;J80B1033CENHI<984::B134?=KO?H8M90F:G141<91948J<8D:23644JOH>4LJK27C3E=338O?N99JM3D0104G>K13<:L?K013:A176IJ:?<6<65B:125C5I93>4OO>23;GB7C3JHK:>=;N3G14<136N=K;38JJUSS2MC[M1?50?32?76<5OTVSQQ14191A147K;NI=56J52;@A1B><=IIN;770G4A0=5DK?98>88:02656624=?2562@D[YY4kioc?75<76890?<4FNQWW>aoij59;6=0>5:12>JSSX\^1hb{{a=13>586=29:6B[[PTV9`jssj59;6=0;0:1714428J2:O<6>F4;565D38>23J=::66;G717AKO9;;I7=8Gf87v378l|z==>"452805EB=MLHM4OL82@0E=I4N6>E02A05=3:KL88O==16CE<@@>8>93NNOM9D54GD57L=<9=?KO697D;563B;H774753D?EK0HH4OO642;FE5351JNI99H9206:5=C1:1>;796;57D20@?C==339?<79CC35G1BKKNN:KO=9K6MA@@5077F>K8J89>448C56F7?<>?NO;H7C6;6A042IK2:?O>769;;7D@1NH?41964537<<;>98?;0126057389?;9?5523042798:><8:?51674>36?J9N5OH;0G35E=35?:O3:?H9F7D32D@A?KK=II<7A45E0D24;9LN=H<:B31FEA273<;3HI;8J>3M<56M84@2@7GFKO:=>9?872D;21D1;=:09:KL7BC;44060H<>=;;I=48K92G0=0168M<:I5M:A2@FEA52L:K9N;:J86563?3E6;=:3=<6:0EG21G5>1MI28O6N7D6;21BAL9H=H>HK8977@<4A08?I?I7K32;AA16<>O:2NI6>AE3163?7>=JN396FE5EFD9366G@C<>;>M57>C@@E@2D>K=8N4>?<444:33?ALKK?<69?EB@E=@5>0<70M;8;N6I3G5AGA3>K:187F30D0I9OIM47925364726<9I?=OL>D91G05=0JOLO?OOJE23E<<3F80JOI8I<=?03DG512BJH=:HI?=ECF0@G2382=NJ?=84EF1AAEA?H>NO96K05115G55LM2I=OJ<4E015073L;;?H>>N9G@27@16:1>;75<:8D515DE?I8K2:??=07;625B6KOK3>=OKA1F73A1B>K92?;==0750B4G5;;3OO9>49EAAGF23MLOL;>8;?B5:336G1;LKJHIKNCE@@GDD1JL2>?;>65@F74>G3?KIMN?8L30A57@4FJ9;:JL7L1033A16C<>H>82GD6G<@1::8>9:8<9G:G27273HN?I99B@ATF4=437LJKR@>6:==FLMXJ0;07;@FGVD:0611JHI\N<9611JHI\M<1<;?DBCZK6:255NDEPA878?3HNO^O2<>99B@ATE4=437LJKRC>6:==FLMXI0;07;@FGVG:0611JHI\M<96=:0MK6MB4:61A4>0>I3;?J=F2;5@<3?988H4>K<<8?C@C45<45;192O;676B47<@E?L?KN8<8;7121726>IO>;;;6M03G57>DR:11IY^QFNGM74>E10J29<89=19@@160FKL:H?K?6C44A15GCJ>39H5;=F93E@465J;::8O<<325B<6273JH2HI:?6D;@FA3BL>LI4?:97@61B2E6KM8N;I7K22F;6C7?:;L3=NEKCK30OBCBIUVF@42O5::NB9133D@70JLHI5KI010:327AML<8II=JD@G5AG2>K=NH;=983D40EDDE<91O5H=?KM0=2N>84DHC?4;169GMD:6;7=0HDO315<:?AOF48?1<394DHC?50813MCJ0<09;EKB87813MCJ0>09;EKB81813MCJ0809;EKB83813MCJ0:09;EKB8=813MCJ0409;EKA85803MCI0<>17:FJF9766>1OEO2>2?58@LD;9:4<7IGM<06==>BNJ5;>6=08;EKA8439>2NBN1?16:FJF949>2NBN1=16:FJF929>2NBN1;16:FJF909>2NBN1916:FJF9>9>2NBN1717:FJTD:7601OE]O31;2=3>BNXH6:2:5KIQ@?4;?69GMUD;97<0HBO30?58@JG;994<7IAN<03=3>BHI5;92:5KO@>27;14=7IAN<9<5?AIF404=7IAM<1<4?AIE48:5;6J@B=32:2=CGK6:>394DN@?56803MEI0<:19:FLF972294<7IAM<07=2>BHJ5;5:6J@B=0=2>BHJ595:6J@B=6=2>BHJ5?5:6J@B=4=2>BHJ5=5:6J@B=:=2>BHJ535;6J@P@>3:<=CGYK7=7>17:FLTD:66>1OC]L30?;8@JVE480;2:5KOQ@?5;273L9:?N7I01A2320C<9N;I87L64435D2B=LHN>L=JC3;55GE1=J;;M89712253F429=:0I5JN26;46@07>MII:8M>2BF34=C>:8:HN2>;OHM9ON5B4:3C6E><3=8=5JC451442A?M3MM;H7F93AG3>4K=O2?=96C3;4A124N:K:8O7:F0FF5G?A8L?>98L<;DLB7>CIJ=:0J49KC90@<<7E9L;JJ>L9B3@:6174?8=3JN6NC@GEA506;J3O4=KK82@E<56698HI=6I<;FLG<>OIA]ZT<=64IOKWTZ6602CEEY^P03:8MKOSXV:846GAIUR\41>:8:KMMQVX8?20ECG[P^243>OIA]U;<:5FNHV\441M7:KMMQY7K>1BBDZP0E58MKOSW9O<7D@FT^2E3>OIA]U:<:5FNHV\541469JJLRX9<=0ECG[_044?LHN\V;<;6GAIU]2<2=NF@^T=494IOKW[4G03@DBXR?M7:KMMQY6K>1BBDZP1E58MKOSW8O<7D@FT^3E3>OIA]U9<:5FNHV\641494IOKW[7G03@DBXR1BBDZP2E58MKOSW;O<7D@FT^0E3>OIA]U8<:5FNHV\741<8;HLJPZ54?2CEEYQ<469JJLRX;<=0ECG[_244?LHN\V9<;6GAIU]0<2=NF@^T?494IOKW[6G03@DBXR=M7:KMMQY4K>1BBDZP3E58MKOSW:O<7D@FT^1E2>OIA]UJ:6GAIU]A2>JHIMOO;6B@GHABHf=JiceyZh||inl`?Hoig{\n~~g`n39M56=I9990B359M54233G;:995A1047?K76?=1E=<6;;O32=6=I9;>0B<2668J44?<2D:>4=4N017?K748=1E=>?;;O3061=I9:9?7C?<459M56333G;8:95A1257?K740=1E=>7<;O370>H6<9>0B<:>4:L2072886@>4568J422<2D:8;:4N0640>H6<1>0B<:63:L211=I9<:?7C?:159M50433G;>?95A1467?K72=:1E=;=4N050?K7?;2D:5?5A229M655H5?:1E>5=4N3;1?K543G9;?6@<129M7759<;O1;7>H41;1E8>5A4118J1743G>9?6@;329M0343:QJIZEHDECXEB@PCIG@O3=TG\XHI:5\RWCO[D1<[[\J@RL;;RQQE1=T[[H?7YW_E518Q5)edbUfi`Qheogqeqiu'kgei lsup,vdkkgfzP

#|nm.fs5=~60'xjal5ZSDP\EIOF[j1^_H\PVHQJFIC43_IH56XFEV]W]UC43^OJ?6YJBc9TVLRBWOCY_Ym4WSKWAZKHLLUJo6Y]IUG\IJBBWK;o7UGCIOZ.\AD'8';+_Y[M 1,2$DUDA@<0T^ZCIC58\VRXOGN<7U][_WA@f>^XKFXNSD@IO79[`gYNlo1SheQ_rhoUawungg;;7Ujb_LcikwPbzzcdb<>4Xeo\Ilhhz_oydaa8:cg`wg/8 20mij}a)3*<>gcl{k#>$64aefqe-5.02koho'4(:8eabui!?"46okdsc+2,>gcl{k7<364aefqe97902koho32?:8eabui59546okdsc?0;>720mij}a=5=<>gcl{k743o4aefqe9?=8720mij}a=;=<>gcl{h#<$64aefqf-7.02kohl'2(:8eabuj!9"46okds`+0,> 20mij}b)5*<>gcl{h#4$64aefqf-?.02kohl30?:8eabuj5;546okds`?6;>gcl{h7:364aefqf91902kohl38?c8eabuj531<364aefqf9?9:o1i`fQbel]dakYq9V;',Ugcioz#GJTB(Noeio{os"24+7)8:9:7nok/qpl}`esgz%fx>< dqpbiv)sey%Toj!kpscn272;8$ekb:4cmib0>ekck=0hd`n(1+4?aoii!;"46jfn`*24,>bnfh":8$64dhlb,43.02nbbl&>6(:8`lhf 8="46jfn`*2<,>;'7;ekme-40!11oeco'29+;?aoii!82%:5kioc+7,>>&7:fjjd.3!>1oeco'5(58`lhf ?#<7igaa)5*3>bnfh"3%:5kioc+=,199gmkg;9<437igaa=35:==cagk7=:07;ekme97?611oeco318<4?aoii5;546jfn`>14;>bnfh698364dhlb873902nbbl2=6?:8`lhf4;=546jfn`>1<;>69gmkg;=7=0hd`n<7<4?aoii5=5;6jfn`>;:2=cagk75394dhla,5/03mcen%?&8:fjjg.68 20hd`m(03*<>bnfk":>$64dhla,45.02nbbo&>4(:8`lhe 8?"46jfnc*22,>bnfk"9%55kio`+65/?3mcen%<>)99gmkd/:;#37igab)00-==cagh#>9'7;ekmf-42!11oecl'27+;?aoij!8<%55kio`+6=/?3mcen%<6)69gmkd/; 20hd`m(22*3>bnfk"?%:5kio`+1,1&8:flqqg/9 30hb{{a)33-<=cg|~j$3me~xl&>7(;8`jssi!;3%45kotvb,4?.02ndyyo'2(;8`jssi!8;%45kotvb,77.12ndyyo'23+:?air|h"9?$74dnwwe-43!01ocxzn(37*=>bh}}k#>;'6;emvpd.5? 30hb{{a)0;-<=cg|~j$?7&8:flqqg/; 30hb{{a)13-==cg|~j$9'7;emvpd.2!11ocxzn(7+;?air|h"<%55kotvb,=/?3me~xl&6)99gkprf494i7iazt`>04?6902ndyyl'0(:8`jssj!;"56j`uu`+55/>3me~xo&>1(;8`jssj!;9%45kotva,45.12ndyyl'15+:?air|k":9$74dnwwf-71!01ocxzm(05*=>bh}}h#=5'6;emvpg.61 20hb{{b)0*=>bh}}h#>='6;emvpg.59 30hb{{b)01-<=cg|~i$?=&9:flqqd/:=#27iaztc*11,?374dnwwf974601ocxzm<06==>bh}}h7=806;emvpg:6>730hb{{b=34:<=cg|~i0<619:flqqd;90437iaztc>2:<=cg|~i0?>19:flqqd;:8427iaztc>16;?89gkpre4;>556j`uu`?608>3me~xo2=6?;8`jssj58<245kotva87>912ndyyl328<;?air|k692o5kotva866=8730hb{{b=13:==cg|~i0>07;emvpg:3611ocxzm<4<;?air|k6=255kotva828?3me~xo27>99gkpre404i7i~}al410}56:?1o|ob636{74*edbUfi`Qheo]u5Z7+FFDN CAAE3d6?avuid<98u=>,cnh[hcjWnoeS{?P1-y`[mgtW{olohl20-a\lduXzlmhil3?,b]nahYsqyo6=!mPh`q\ip~Xg|~{yyQ}efq>4)eXx{cfSywe<3/gZunf`~jS{oc=1.`[wcflV}bhyfPb<12(fYumhnT{dj{h^c>74*dWmcxmobj_vcqjZdo~Vid`a3?,b]jjlrXn`fnScobe9"l_vpjp`Ycmy~cSl3925.`[mgtWzyyn0>#c^jbwZutzh7; nQndepb[roc|a7:#c^cocjtn|ag6=!mPdhqbficXhxeSofy_scmc`;7$jUcm~Qbel]lqqvr|Vxnk~3?,b]tvlrbW~coxeQm=23/gZqua}oT{dj{h^c>74*dW{ojhRjjpuj\f805<%iT~hok_egspmYf5?8? nQmyug\wl|b50&hS~gb_bmohlunggUhdhmd=@NO(fYdgdgdbRmck<2/gZqbiV}bhyf21-a\lduXmgh69v<1-a\qvcXjp~nSzkm=1.`[pubWksiRyja<2/gZstmVnnjl{ct^fbpd;7$t897i~}al410}56Wkf`S`kb_fgm[s7X9VrxxR?7;dfjb7h`l:1nbl=4eo`;?kadj|cgh;5}efafe3=umninn95|ssc7?vuuj?1|il&?)99tad:7294=7zkn<1<5?rce 9#37zkm<183:xFGx;n;7MNw1e69B?2=9rY3:7<6a;0g>455j>9m6?9l59ym5d1=92d:m54;;%3b1?7f82wX494=9`81`?74:k=8j7<8c4:8W44d2;3o6=4>33`47c<5?j?27^6;:3;g>5<6;;h>3:1=7?tS949601|[1<1>4o52e8277d0;o09;n;7;%3:e?75l2\:m;4={t31a?7<}88m6=5r$0:b>1d67=;;0?57:9:|&2=1<51?1/=l:51e18m7g5290/=5m52`18j4>e2910ee2810ee2:10ee2<10ee2>10e290/=5m51ca8j4>e2010ee2810ee2:10ee2<10e:18'5=e=9m;0b<6m:798m4e7290/=5m51e38j4>e2>10ee2010c?8i:18'5=e=:1n0b<6m:198k70c290/=5m529f8j4>e2810c?8l:18'5=e=:1n0b<6m:398k70e290/=5m529f8j4>e2:10c?8n:18'5=e=:1n0b<6m:598k70>290/=5m529f8j4>e2<10c?87:18'5=e=:1n0b<6m:798k700290/=5m529f8j4>e2>10c?89:18'5=e=:1n0b<6m:998k702290/=5m529f8j4>e2010c?8;:18'5=e=:1n0b<6m:`98k705290/=5m529f8j4>e2k10c?8>:18'5=e=:1n0b<6m:b98k707290/=5m529f8j4>e2m10c?;i:18'5=e=:1n0b<6m:d98k73b290/=5m529f8j4>e2o10c?;k:18'5=e=:1n0b<6m:028?j42k3:1(<6l:3:g?k7?j3;:76a=5c83>!7?k383h6`>8c826>=h:8b8154o37:>5<#91i1>5j4n0:a>42<3f8<97>5$0:`>7>c3g;3n7?:;:m131<72-;3o7<7d:l221d>:=50;&2e28207b<81;29 4>d2;2o7c?7b;3:?>i5?90;6)?7c;0;`>h60k0:m65`27g94?"60j094i5a19`95g=e:9j5a3=831b=i850;9j5``=83.:4n4=0e9m5=d=821b=hj50;&2=83.:4n4=0e9m5=d=>21b=h950;&250;&2d`83>!7?k38;h6`>8c827>=n9m31<7*>8b814a=i91h1=954i0d6>5<#91i1>=j4n0:a>43<3`;m87>5$0:`>76c3g;3n7?9;:k2b6<72-;3o7e28307d?i0;29 4>d2;:o7c?7b;3b?>o6ml0;6)?7c;03`>h60k0:n65f1d194?"60j09k;o3;f?7b32h:544?:083>5}O9020(<7;:0;:?j7?13:17plj1;295?6=8rB:555+1869a4=hm90;66sm7e83>1>=<00?:7:8:5:90<<4j39h6>?533872?202t.:594=989'<4<51>1/484=999'5=0=9120e?7m:188m7?d2900e?o?:188m7g62900e?7j:188m7?a2900e?o=:18'5=e=:h90b<6m:198m7g2290/=5m52`48j4>e2910ee2810ee2:10ee2<10ee2>10e290/=5m51ca8j4>e2010ee2810ee2:10ee2<10e:18'5=e=9m;0b<6m:798m4e7290/=5m51e38j4>e2>10ee2010c?:j:18'5=e=:<<0b<6m:198k72d290/=5m52448j4>e2810c?:m:18'5=e=:<<0b<6m:398k72f290/=5m52448j4>e2:10c?:6:18'5=e=:<<0b<6m:598k72?290/=5m52448j4>e2<10c?:8:18'5=e=:<<0b<6m:798k721290/=5m52448j4>e2>10c?:::18'5=e=:<<0b<6m:998k723290/=5m52448j4>e2010c?:<:18'5=e=:<<0b<6m:`98k726290/=5m52448j4>e2k10c?:?:18'5=e=:<<0b<6m:b98k75a290/=5m52448j4>e2m10c?=j:18'5=e=:<<0b<6m:d98k75c290/=5m52448j4>e2o10c?=l:18'5=e=:<<0b<6m:028?j44j3:1(<6l:375?k7?j3;:76a=3`83>!7?k38>:6`>8c826>=h::31<7*>8b8113=i91h1=>54o31;>5<#91i1>884n0:a>42<3f8>87>5$0:`>7313g;3n7?:;:m116<72-;3o7<:6:l221d>8<50;&2e28207b<:0;29 4>d2;?=7c?7b;3:?>i5h60k0:m65`25f94?"60j099;5a19`95g=96=4+19a96002d:4o4>e:9l63`=83.:4n4=8e9m5=d=821d>;j50;&2;l50;&2;750;&2=83.:4n4=8e9m5=d=>21d>;950;&2;;50;&2;<50;&2;>50;&28k50;&2!7?k383h6`>8c827>=h:<31<7*>8b815<#91i1>5j4n0:a>43<3f8<87>5$0:`>7>c3g;3n7?9;:m136<72-;3o7<7d:l2:<50;&2e28307b<80;29 4>d2;2o7c?7b;3b?>i5>l0;6)?7c;0;`>h60k0:n65`27194?"60j094i5a19`95f=32c:i94?:%3;g?47l2d:4o4n;:k2a7<72-;3o70:9j5ae=83.:4n4=0e9m5=d=9810ed883>!7?k38;h6`>8c820>=n9o?1<7*>8b814a=i91h1=854i0d7>5<#91i1>=j4n0:a>40<3`;m?7>5$0:`>76c3g;3n7?8;:k2b7<72-;3o7e28k07d?je;29 4>d2;:o7c?7b;3a?>o6m:0;6)?7c;03`>h60k0:o65f1e:94?"60j095$0:`>7523g;3n7?4;h01f?6=,82h6?=:;o3;f?4<3`89m7>5$0:`>7523g;3n7=4;h01=?6=,82h6?=:;o3;f?2<3`8947>5$0:`>7523g;3n7;4;h013?6=,82h6?=:;o3;f?0<3`89:7>5$0:`>7523g;3n794;h011?6=,82h6?=:;o3;f?><3`8987>5$0:`>7523g;3n774;h017?6=,82h6?=:;o3;f?g<3`89=7>5$0:`>7523g;3n7l4;h014?6=,82h6?=:;o3;f?e<3`8:j7>5$0:`>7523g;3n7j4;h02a?6=,82h6?=:;o3;f?c<3`8:h7>5$0:`>7523g;3n7h4;h02g?6=,82h6?=:;o3;f?7732c9=o4?:%3;g?44=2d:4o4>1:9j64g=83.:4n4=349m5=d=9;10e??6:18'5=e=::?0b<6m:018?l4603:1(<6l:316?k7?j3;?76g=3583>!7?k38896`>8c821>=n::91<7*>8b8170=i91h1=;54i311>5<#91i1>>;4n0:a>41<3`88=7>5$0:`>7523g;3n7?7;:k175<72-;3o7<<5:l2?h50;&2e28h07d<=2;29 4>d2;9>7c?7b;3`?>o59>0;6)?7c;001>h60k0:h65f20494?"60j09?85a19`95`=:183!7><3o:7E?n1:J2===hm90;66sm1`194?7=83:p(<7;:0;:?M7f92B:555`19;94?=zj83=6=494;294~"61=0:4i5G1`38L4??3S=n6lu=f;13>63=;?0?=7:=:25906<403>?6p*>2981?!751380(h<52d9'a6<292.n87=<;%g6>62<,l<1?6*j7;08 4?7281/=4?51:&fe?763-oi6?64$da957=#mm09:6*je;3e?!ca2;;0(k>5169'b476<,o31>:5+f`81g>"aj38j7)hl:69'ba1=95+11796<=#99<1n6*>0682`>"6810::6*>088f?!77i3;;7)??b;0a?!77k3l0(<>k:99'55c=12.:b:&255<23-;:=7<4$031>7=#9891>6*>1581?!76=380("69j097)?>d;08 47b2;1/=7=#9;91>6*>2581?!75=380(<<9:39'571=:2.:5k4>9e9'a=<53-;3i79m;%31e?7<,88i6<5+18g956g72;29?l>42900eij50;9j``<722c:5?4?::k2=6<722c:5o4?::k2=f<722c=i7>5$0:`>3b8c82?>o1j3:1(<6l:7f8j4>e2;10e;o50;&21=8b85`>h60k0>76g97;29 4>d2?n0b<6m:798m30=83.:4n49d:l25$0:`>3b8c8:?>o013:1(<6l:6:8j4>e2910e:950;&2;:k42?6=,82h6:64n0:a>7=?1<7*>8b84<>h60k0876g84;29 4>d2>20b<6m:598m25=83.:4n488:l27>5$0:`>2>8c84?>o083:1(<6l:6:8j4>e2110e;h50;&24n0:a>5=8b8:4>h60k0:76g7e;29 4>d20:0b<6m:398m=b=83.:4n460:l25$0:`><68c86?>o>i3:1(<6l:828j4>e2?10e4750;&282d:4o48;:k:4n0:a>==8b8:4>h60k0276g66;29 4>d20:0b<6m:`98m<3=83.:4n460:l25$0:`><68c8g?>o>:3:1(<6l:828j4>e2l10e5o50;&282d:4o4i;:kb6?6=,82h6l?4n0:a>5=8b8b5>h60k0:76g6f;29 4>d2h;0b<6m:398m5$0:`>d78c86?>ofj3:1(<6l:`38j4>e2?10elo50;&2==8b8b5>h60k0276gn7;29 4>d2h;0b<6m:`98md0=83.:4n4n1:l25$0:`>d78c8g?>of;3:1(<6l:`38j4>e2l10e4l50;&25=8b8b`>h60k0:76gm1;29 4>d2k:0b<6m:198md`=83.:4n4m0:l25$0:`>g>8c82?>ie>3:1(<6l:c:8j4>e2;10co;50;&21=8b8a<>h60k0>76al2;29 4>d2k20b<6m:798kf7=83.:4n4m8:l25$0:`>g>8c8:?>iem3:1(<6l:c:8j4>e2h10coj50;&2f=8b8a<>h60k0o76ama;29 4>d2k20b<6m:d98kg4=83.:4n4m8:l25$0:`>a38c82?>idi3:1(<6l:b;8j4>e2910cn650;&2;:m`3?6=,82h6n74n0:a>7=8b8`=>h60k0876al5;29 4>d2j30b<6m:598kf2=83.:4n4l9:l25$0:`>f?8c84?>ic93:1(<6l:b;8j4>e2110ci>50;&2d=8b8`=>h60k0i76ald;29 4>d2j30b<6m:b98kfe=83.:4n4l9:l25$0:`>f?8c8e?>ic13:1(<6l:e:8j4>e2910ci950;&2;:a5<3=83>534802?262=81?:4;3;1;>12=u-;947<4$00:>7=#m;08h6*j3;30?!c32=i0(h;5449'a3<33-o<6?5+18295>"6180:7)kn:428 `d=011/in4:d:&f`?3>3-on6;<4$dd90a=#n90on6*i1;7;?!`52=:0(k=53g9'b1<0k2.m97ji;%d5>1g<,o=1hl5+f986g>"a13?97)hn:2g8 cd=5+111913=#99>1:>5+11797d=#99<19l5+1159<<=#99219h5+11;97<=#99k1;l5+11`9<5=#99i14:5+11f91c=#99o1:<5+11d911=#98:19:5+10396>"69;097)?>3;08 4732;1/=<;52:&253<53-;:;7<4$03;>7=#9831>6*>1`81?!76j380("6:;097)?=3;08 4432;1/=?;52:&263<53-;9;7<4$0;e>4?c3-o36?5+19g93g=#9;k1=6*>2c82?!7>m3;2h6*j9;08m=4=831b4>4?::kg`?6=3`nn6=44i0;1>5<5<8c83?>o1k3:1(<6l:7f8j4>e2810e;l50;&26=8b85`>h60k0?76g98;29 4>d2?n0b<6m:498m31=83.:4n49d:l25$0:`>3b8c8;?>o1<3:1(<6l:7f8j4>e2010e:750;&24=<1<7*>8b84<>h60k0976g85;29 4>d2>20b<6m:298m22=83.:4n488:l25$0:`>2>8c85?>o093:1(<6l:6:8j4>e2>10e:>50;&2<=8b8:4>h60k0;76g7f;29 4>d20:0b<6m:098m=c=83.:4n460:l25$0:`><654i9a94?"60j02<6`>8c87?>o?j3:1(<6l:828j4>e2<10e4o50;&282d:4o49;:k:=?6=,82h64>4n0:a>2=8b8:4>h60k0376g67;29 4>d20:0b<6m:898m<0=83.:4n460:l25$0:`><68c8`?>o>;3:1(<6l:828j4>e2m10e4<50;&282d:4o4j;:k;e?6=,82h64>4n0:a>c=8b8b5>h60k0;76gn0;29 4>d2h;0b<6m:098m<`=83.:4n4n1:l25$0:`>d754i8f94?"60j0j=6`>8c87?>o>k3:1(<6l:`38j4>e2<10ell50;&22=8b8b5>h60k0376gn8;29 4>d2h;0b<6m:898md1=83.:4n4n1:l25$0:`>d78c8`?>of<3:1(<6l:`38j4>e2m10el=50;&2c=8b8b`>h60k0;76gnc;29 4>d2hn0b<6m:098mg7=83.:4n4m0:l25$0:`>g68c83?>ie?3:1(<6l:c:8j4>e2810co850;&26=1<7*>8b8a<>h60k0?76am3;29 4>d2k20b<6m:498kf4=83.:4n4m8:l25$0:`>g>8c8;?>ien3:1(<6l:c:8j4>e2010cok50;&2g=8b8a<>h60k0h76amb;29 4>d2k20b<6m:e98kgg=83.:4n4m8:l27>5$0:`>g>8c83?>ic<3:1(<6l:e78j4>e2810cno50;&24=8b8`=>h60k0976al6;29 4>d2j30b<6m:298kf3=83.:4n4l9:l25$0:`>f?8c85?>ic:3:1(<6l:b;8j4>e2>10ci?50;&2<=8b8`=>h60k0j76ale;29 4>d2j30b<6m:c98kfb=83.:4n4l9:l25$0:`>f?8c8f?>id;3:1(<6l:b;8j4>e2o10ci750;&24=53z\2`0=:90<14?521879<7=z{8n=6=4<{_3g2>;61?03?63>948;7>{t:X59l4^36b?[4312T9855Q2558Z7213W8?96P=459]615:7S<;0:\17c=Y::o0R?=k;_00g>X5;k1U>>o4^31:?[4402T9995Q2418Z7353W8>=6P=519]61`o7S<;2:\172=Y::<01;61?0:5n521849=4=:90<14k521849<`=:90<14i521849e7=:90<1m=521849=c=:90<15h521849=a=:90<15n521849eg=:90<1ml521849e<=:90<1m5521849e2=:90<1m;521849e0=:90<1m9521849e6=:90<15o521849e`=:90<1n<521849ec=:90?1=4<4=0;6>4?434;297?6c:?2=0n27:5846e:?2=0<>l27:5846c:?2=0;61?0o>6s|29:94?4|V;0;6?uQ27;894?12m;0q~<76;296~X5>116=485d19~w7>22909wS<97:?2=35:50;0xZ70134;2:7mj;|q1<6<72;qU>;;4=0;5>fb7>52z\121=:90<1on5rs3:3>5<5sW8=>63>978`f>{t:>l1<7>3i87p}=7d83>7}Y:?:01<7::e;8yv40l3:1>vP=5g9>5<3=kh1v?9l:181[42m27:584l8:p62d=838pR?;k;<3:1?e03ty9;l4?:3y]60e<583>6n84}r04=?6=:rT99o521879g0=z{;=36=4={_06e>;61<0h86s|26594?4|V;?270?65;f0?xu51<0;6?uQ267894?22m80q~<64;296~X5?=16=4;5d69~w7?42909wS<83:?2=04<50;0xZ71534;297j?;|q1=4<72;qU>:?4=0;6>f`52z\135=:90?1oh5rs3:e>5<5sW8=i63>948``>{t:1i1<7=3ih7p}=8083>7}Y:<201<7::b`8yv40>3:1>vP=569>5<3=k:1v?o;:180[4f:27:5;4>9c9>5<3=90h0q~?md;297~X6j;16=4856d9>5<3=>l1v3g53z\2e`=:90<1:45218792<=z{8h<6=4<{_3b`>;61?0=463>9485<>{t9k<1<7=t^0c`?87>>3<<70?65;44?xu6j<0;6>uQ1``894?12?<01<7::748yv7e<3:1?vP>a`9>5<0=><16=4;5649~w4d42908wS?n9:?2=3<1<27:58494:p5a4=839pR34;29796;|q2`5<72:qU=n84=0;5>21<583>6:94}r3`b?6=;rT:o852184933=:90?1;;5rs0af>5<4sW;h863>97841>;61<0<96s|1bf94?5|V8i870?66;57?87>=3=?7p}>cb83>6}Y9j801<79:61894?22>90q~?lb;297~X6k816=485739>5<3=?;1v3`52z\2ac=:90<14n5rs32a>5<5sW;nh63>978;f>{t:9k1<7>33j7p}=0883>7}Y9lh01<79:8;8yv4703:1>vP>e`9>5<0=ij1v?>8:181[7b127:5;468:p650=838pR;61?0286s|21094?4|V8o?70?66;;0?xu5890;6?uQ1d0894?12080q~?if;296~X6m816=4858`9~w4`b2909wS?j0:?2=0;|q2bf<72;qU=ik4=0;6>=`52z\2`a=:90?14h5rs0db>5<5sW;oo63>948;`>{t9o31<7=32h7p}>f983>7}Y9mk01<7::9`8yv7a?3:1>vP>d89>5<3=1h1v??::181[7a=27:58469:p642=838pR4?:3y]5c5<583>6464}r026?6=:rT:j?521879=2=z{;;:6=4={_3e5>;61<02:6s|20294?4|V8l;70?65;;6?xu58o0;6?uQ1dg894?220>0q~:2wx=k850;0xZ4b034;2976n;|q275<720;6?uQ1d;892b=9l30(<78:0:7?xu58?0;6?uQ1d:892b=9l20(<78:0:6?xu58<0;6?uQ1d5892b=9l=0(<78:012?xu58=0;6?uQ1d4892b=9l<0(<78:011?xu58:0;6?uQ1d7892b=9l?0(<78:01`?xu58;0;6?uQ1d6892b=9l>0(<78:060?xu5890;6?uQ1d0892b=9l80(<78:06f?xu6no0;6?uQ1d3892b=9l;0(<78:07:?xu6nl0;6?uQ1d2892b=9l:0(<78:043?xu6nm0;6?uQ1ed892b=9ml0(<78:042?xu6nj0;6?uQ1eg892b=9mo0(<78:041?xu6nk0;6?uQ1ef892b=9mn0(<78:040?xu6nh0;6?uQ1ea892b=9mi0(<78:046?xu6n00;6?uQ1e`892b=9mh0(<78:045?xu6n10;6?uQ1ec892b=9mk0(<78:044?xu6n>0;6?uQ1e;892b=9m30(<78:04;?xu59<0;6?uQ1g7892b=9o?0(<78:04:?xu59=0;6?uQ1g6892b=9o>0(<78:04b?xu59:0;6?uQ1g1892b=9o90(<78:04a?xu59;0;6?uQ1g0892b=9o80(<78:04`?xu5980;6?uQ1g3892b=9o;0(<78:04g?xu5990;6?uQ1g2892b=9o:0(<78:04f?xu58o0;6?uQ1dg892b=9lo0(<78:053?xu58j0;6?uQ1d1892b=9l90(<78:052?xu5880;6?uQ1e:892b=9m20(<78:051?xu6n?0;6?uQ1e5892b=9m=0(<78:050?xu6jm0;6?uQ1c0892b=9k80(<78:057?xu6jk0;6?uQ1c3892b=9k;0(<78:056?xu6jh0;6?uQ1c2892b=9k:0(<78:055?xu6j00;6?uQ1`d892b=9hl0(<78:054?xu6j10;6?uQ1`g892b=9ho0(<78:05;?xu6j>0;6?uQ1`f892b=9hn0(<78:05:?xu6j?0;6?uQ1`a892b=9hi0(<78:05a?xu6j<0;6?uQ1``892b=9hh0(<78:05`?xu6j=0;6?uQ1`c892b=9hk0(<78:05g?xu6j:0;6?uQ1`;892b=9h30(<78:05f?xu5i=0;6?uQ2`0892b=:h80(<78:05e?xu6l?0;6?uQ1e4892b=9m<0(<78:0:0?xu6l;0;6?uQ1b5892b=9j=0(<78:010?xu6l90;6?uQ1b4892b=9j<0(<78:017?xu6ko0;6?uQ1b7892b=9j?0(<78:016?xu6kl0;6?uQ1b6892b=9j>0(<78:015?xu6km0;6?uQ1b1892b=9j90(<78:014?xu6kj0;6?uQ1b0892b=9j80(<78:01;?xu6kk0;6?uQ1b3892b=9j;0(<78:01:?xu6kh0;6?uQ1b2892b=9j:0(<78:01b?xu6k00;6?uQ1cd892b=9kl0(<78:01a?xu6k10;6?uQ1cg892b=9ko0(<78:01g?xu50l0;6?uQ27d892b=:?l0(<78:01f?xu50k0;6?uQ27f892b=:?n0(<78:01e?xu50h0;6?uQ27a892b=:?i0(<78:063?xu5000;6?uQ27`892b=:?h0(<78:062?xu5010;6?uQ27c892b=:?k0(<78:061?xu50>0;6?uQ27;892b=:?30(<78:067?xu50?0;6?uQ27:892b=:?20(<78:066?xu50<0;6?uQ275892b=:?=0(<78:065?xu50=0;6?uQ274892b=:?<0(<78:064?xu50:0;6?uQ277892b=:??0(<78:06;?xu50;0;6?uQ276892b=:?>0(<78:06:?xu5090;6?uQ270892b=:?80(<78:06b?xu5?o0;6?uQ273892b=:?;0(<78:06a?xu5?l0;6?uQ272892b=:?:0(<78:06`?xu5?m0;6?uQ24d892b=:0;6?uQ24;892b=:<30(<78:077?xu51<0;6?uQ267892b=:>?0(<78:076?xu51=0;6?uQ266892b=:>>0(<78:075?xu51:0;6?uQ261892b=:>90(<78:074?xu51;0;6?uQ260892b=:>80(<78:07;?xu5180;6?uQ263892b=:>;0(<78:07b?xu5190;6?uQ262892b=:>:0(<78:07a?xu50o0;6?uQ27g892b=:?o0(<78:07`?xu50j0;6?uQ271892b=:?90(<78:07g?xu5080;6?uQ24:892b=:<20(<78:07f?xu5??0;6?uQ245892b=:<=0(<78:07e?x{i:;>1<73:1>vF>999~j7402909wE?68:m67>=838pD<77;|l16<<72;qC=464}o01e?6=:rB:555rn30a>5<5sA;246sa23a94?4|@8337p`=2e83>7}O9020qc<=e;296~N6111vb?02we>>>50;0xL4??3td9?<4?:3yK5<>7>52zJ2===zf;986=4={I3:<>{i::>1<73:1>vF>999~j7502909wE?68:m66>=838pD<77;|l17<<72;qC=464}o00e?6=:rB:555rn31a>5<5sA;246sa22a94?4|@8337p`=3e83>7}O9020qc<02we>9>50;0xL4??3td98<4?:3yK5<>7>52zJ2===zf;>86=4={I3:<>{i:=>1<73:1>vF>999~j7202909wE?68:m61>=838pD<77;|l10<<72;qC=464}o07e?6=:rB:555rn36a>5<5sA;246sa25a94?4|@8337p`=4e83>7}O9020qc<;e;296~N6111vb?:i:181M7>02we>8>50;0xL4??3td99<4?:3yK5<>>7>52zJ2===zf;?86=4={I3:<>{i:<>1<73:1>vF>999~j7302909wE?68:m60>=838pD<77;|l11<<72;qC=464}o06e?6=:rB:555rn37a>5<5sA;246sa24a94?4|@8337p`=5e83>7}O9020qc<:e;296~N6111vb?;i:181M7>02we>;>50;0xL4??3td9:<4?:3yK5<>7>52zJ2===zf;<86=4={I3:<>{i:?>1<7<0;6?uG18:8yk41>3:1>vF>999~j7002909wE?68:m63>=838pD<77;|l12<<72;qC=464}o05e?6=:rB:555rn34a>5<5sA;246sa27a94?4|@8337p`=6e83>7}O9020qc<9e;296~N6111vb?8i:181M7>02we>:>50;0xL4??3td9;<4?:3yK5<>7>52zJ2===zf;=86=4={I3:<>{i:>>1<73:1>vF>999~j7102909wE?68:m62>=838pD<77;|l2gc<728qC=464}o017?6=9rB:555r}|CDF}5l908ihk"9 > %7845678=:0<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;8=5?01234563<9:><9;>0572546799??==:>1572553388>:9=:>1063056699?>98:;0:23456789K9;8KN=OMCC63?565?9I:;=:I6001G444?9N;4=L7501F34C2993I8=:?A0177406L8>8N=78312BG16<89>3<8J?002G5=1?8J;O8CA22G67>K?;I8>>D223=236IL8:H5>>F163F=1700=::I7>C633=0768LI?<6>:143E0571=?;N9L?61C3:@F7FK1;OH??<763E0=73L<:;99>>722GEF60N;:NN<:?;14;4157N82;O;8;A6:F4CD788O=;N23D;B7E00O8;9K>;252843?58;:I601AF46G699N80N:5L8?C133@89223<7698O:>:O>78G2E7E382:=O77214@6F18;>4;7=9?81FG446299228<6M6171B44EN9K=I408@74<<>8=0CFE425C8??;=4?N060257419M>J=4O:146E4C6E99;=<:6M4193E1@69;:;O;6?8BA3<7378MH;9?<>01;3A<7651274>6F?9:9>K8134=375J1;9:??I0225052739KI4=JM90@44564M8KJ:=M831:FA5BF9898M=:860:144B3;9NHN=9951C7647>M=:0M=I6N1E2:44?F9O>9=88<137255?28:8842G35C>6;L9:9>H>EDG2=6@7;;0:2AFG668>:9963B0=65L9:JIN?=88274262M9::?N>J6E2B0771IJ;;N=??9@63?5@618=:>=HN2117@51AN82J<<<640D744D418?8J=8K207A<4@5L9OM:<07045FED8H8I:<022G5DBB<91;JI7?53A30G4690N;HL;>96C3@4660=;:8K;>B5223G@7;>9:5I7?E152B2E7IL8?<6>ID83:027CJH:O5=?N3637@C65M?:J:9??DG34G672M;;2I778=?;=8>:143355278<:>9=>?5466017289:;==;:106740679<::=8?>5076017438:1EC^ZT;CG@WG;13:5=>5>0;KMTPR=IMNYN1750?30?46=AGZ^X7okdsc?=?699:1:<7GAPTV9eabuj531<3:?;02AG5C108N29=>;C1A05472:9KHH=68607E<5?A:8>M5A055557>;8NH4=?J75285465893N=>J;14045ACE8M;N7076A521E9;8:=5JI17;;51D19>N=??CE:360G6IM9;8<;>5ED3E7B681H:4>L>16@3A5E7LJO:OHJ?7@22;9;L?:3D36G<70;L:J=K>J0G3E<=75M9>;7J9====JN71GBB45F99:3<=:I01G;=44E098=8413C3464381LO==J704:545369:H<=N7818D:41208<;IN=4M84192056699>?=<;;407645368==:;11635423<<>?98;;0577402799:;88>;45774>73=M;N5?AG2:147E=?:>>;?N1@3:146>0O:;5=>=B621@62738>=N=J970:E74E0K9O9>=:M00AEB4EFI9>N5=96B01:=51C882>8=5>5B:21407ILI;8>6>0BD36=761><::>=>345322D61LI:IIH>A1;3E3@7L:I:<=>;0:355C61J0;IO:>M203E357>0H:M98>K1@37076C>K:<5=?=70230F67KO:>586:2;=6D@_UU8GMG:6=3:5=>5>6;MVPUSS2MEJ0<;50?30?40=G\^[YY4KOC>21?69<91::KL9AE5;412B0ONO9OND1F32@G4;<>?>9983D6B2CBD;M:?<6?9FB3:7=7A00;8?N?<9E314C7?8M;;9N>JBE3@==728H:;OL>LB92;<67B;8:39::?;051=4G3K9?CN8?>KK>58?;1D34F=>E9OK>;3>58682;1EC^ZT;uff96=87>;7D=9?210E65C0M8I3M=MIB15G@5?5=8O>59>41@A@54G09::=A89;?<;=J18715AE598:=HM>FEG3@416L8;:<86>A9C26657I>H:OHJ>7E133A56=HO:MKO>6D274>7D?<;8>>C63@BA2738N>N08:;4=>>701FF4C3K8:OI=:<2126=43BL=:0=I9L0BG24D5>9L:O<9>803C34A739>KJ<<8;1C6A511@746B38MLO8=5>D9C37C17NJ::JHC122B166:MI:<5=>4CG2@C@6K:2;48<;0:3GF3E?IK8H5I=9F7607144JO8BB63?4BC>=L2<4;MM;849<:8476F<>A=MN9:5;79G66722FL:O=N4?K9B61216<9L<<9?L><89905G:410198L3=?LK041;4G648LK;<;M>197:4253<91948J<8D:23644JOH>4LJK27C3E=338O?N99JM3D0104G>K13<:L?K013:A176IJ:?<6<65B:125C5I93>4OO>23;GB7C3JHK:>=;N3G14<136N=K;38JJUSS2MC[M1?50?32?76<5OTVSQQ14191A147K;NI=56J52;@A1B><=IIN;770G4A0=5DK?98>88:02656624=?2552@D[YY4kioc?74<76890??4FNQWW>aoij59:6=0>5:11>JSSX\^1hb{{a=12>586=2996B[[PTV9`jssj59:6=0;0:1714428J2:O<6>F4;565D38>23J=::66;G717AKO9;;I7=8Gf87v378l|z==>"452805EB=MLHM4OL82@0E=I4N6>E02A05=3:KL88O==16CE<@@>8>93NNOM9D54GD57L=<9=?KO697D;563B;H774753D?EK0HH4OO642;FE5351JNI99H9206:5=C1:1>;796;57D20@?C==339?<79CC35G1BKKNN:KO=9K6MA@@5077F>K8J89>448C56F7?<>?NO;H7C6;6A042IK2:?O>769;;7D@1NH?41964537<<;>98?;0126057389?;9?5523042798:><8:?51674>36?J9N5OH;0G35E=35?:O3:?H9F7D32D@A?KK=II<7A45E0D24;9LN=H<:B31FEA273<;3HI;8J>3M<56M84@2@7GFKO:=>9?872D;21D1;=:09:KL7BC;44060H<>=;;I=48K92G0=0168M<:I5M:A2@FEA52L:K9N;:J86563?3E6;=:3=<6:0EG21G5>1MI28O6N7D6;21BAL9H=H>HK8977@<4A08?I?I7K32;AA16<>O:2NI6>AE3163?7>=JN396FE5EFD9366G@C<>;>M57>C@@E@2D>K=8N4>?<444:33?ALKK?<69?EB@E=@5>0<70M;8;N6I3G5AGA3>K:187F30D0I9OIM47925364726<9I?=OL>D91G05=0JOLO?OOJE23E<<3F80JOI8I<=?03DG512BJH=:HI?=ECF0@G2382=NJ?=84EF1AAEA?H>NO96K05115G55LM2I=OJ<4E015073L;;?H>>N9G@27@16:1>;75<:8D515DE?I8K2:??=07;625B6KOK3>=OKA1F73A1B>K92?;==0750B4G5;;3OO9>49EAAGF23MLOL;>8;?B5:336G1;LKJHIKNCE@@GDD1JL2>?;>65@F74>G3?KIMN?8L30A57@4FJ9;:JL7L1033A16C<>H>82GD6G<@1::8>9:8<9G:G27273HN?I99B@ATF4=437LJKR@>6:==FLMXJ0;07;@FGVD:0611JHI\N<9611JHI\M<1<;?DBCZK6:255NDEPA878?3HNO^O2<>99B@ATE4=437LJKRC>6:==FLMXI0;07;@FGVG:0611JHI\M<96=:0MK6MB4:61A4>0>I3;?J=F2;5@<3?988H4>K<<8?C@C45<45;192O;676B47<@E?L?KN8<8;7121726>IO>;;;6M03G57>DR:11IY^QFNGM74>E10J29<89=19@@160FKL:H?K?6C44A15GCJ>39H5;=F93E@465J;::8O<<325B<6273JH2HI:?6D;@FA3BL>LI4?:97@61B2E6KM8N;I7K22F;6C7?:;L3=NEKCK30OBCBIUVF@42O5::NB9133D@70JLHI5KI010:327AML<8II=JD@G5AG2>K=NH;=983D40EDDE<91O5H=?KM0=2N>84DHC?4;169GMD:6;7=0HDO315<:?AOF48?1<394DHC?50813MCJ0<09;EKB87813MCJ0>09;EKB81813MCJ0809;EKB83813MCJ0:09;EKB8=813MCJ0409;EKA85803MCI0<>17:FJF9766>1OEO2>2?58@LD;9:4<7IGM<06==>BNJ5;>6=08;EKA8439>2NBN1?16:FJF949>2NBN1=16:FJF929>2NBN1;16:FJF909>2NBN1916:FJF9>9>2NBN1717:FJTD:7601OE]O31;2=3>BNXH6:2:5KIQ@?4;?69GMUD;97<0HBO30?58@JG;994<7IAN<03=3>BHI5;92:5KO@>27;14=7IAN<9<5?AIF404=7IAM<1<4?AIE48:5;6J@B=32:2=CGK6:>394DN@?56803MEI0<:19:FLF972294<7IAM<07=2>BHJ5;5:6J@B=0=2>BHJ595:6J@B=6=2>BHJ5?5:6J@B=4=2>BHJ5=5:6J@B=:=2>BHJ535;6J@P@>3:<=CGYK7=7>17:FLTD:66>1OC]L30?;8@JVE480;2:5KOQ@?5;273L9:?N7I01A2320C<9N;I87L64435D2B=LHN>L=JC3;55GE1=J;;M89712253F429=:0I5JN26;46@07>MII:8M>2BF34=C>:8:HN2>;OHM9ON5B4:3C6E><3=8=5JC451442A?M3MM;H7F93AG3>4K=O2?=96C3;4A124N:K:8O7:F0FF5G?A8L?>98L<;DLB7>CIJ=:0J49KC90@<<7E9L;JJ>L9B3@:6174?8=3JN6NC@GEA506;J3O4=KK82@E<56698HI=6I<;FLG<>OIA]ZT<=64IOKWTZ6602CEEY^P03:8MKOSXV:846GAIUR\41>:8:KMMQVX8?20ECG[P^243>OIA]U;<:5FNHV\441M7:KMMQY7K>1BBDZP0E58MKOSW9O<7D@FT^2E3>OIA]U:<:5FNHV\541469JJLRX9<=0ECG[_044?LHN\V;<;6GAIU]2<2=NF@^T=494IOKW[4G03@DBXR?M7:KMMQY6K>1BBDZP1E58MKOSW8O<7D@FT^3E3>OIA]U9<:5FNHV\641494IOKW[7G03@DBXR1BBDZP2E58MKOSW;O<7D@FT^0E3>OIA]U8<:5FNHV\741<8;HLJPZ54?2CEEYQ<469JJLRX;<=0ECG[_244?LHN\V9<;6GAIU]0<2=NF@^T?494IOKW[6G03@DBXR=M7:KMMQY4K>1BBDZP3E58MKOSW:O<7D@FT^1E2>OIA]UJ:6GAIU]A2>JHIMOO;6B@GHABHf=JiceyZh||inl`?Hoig{\n~~g`n39M56=I9990B659M54133G;:495A10;0?K75<2D:>=:4N0020>H6:;>0B<<<4:L26=2359M56633G;8=95A1207?K74;=1E=>:;;O3011=I9:33G;85>5A1568J427<2D:8<:4N0610>H6<:>0B<:;4:L2002=86@>4668J42?<2D:84=4N077?K728=1E=8?;;O3661=I9<9?7C?:459M50333G;>:95A1457?K720=1E=87<;O357>H6?:1E=5=4N0;1?K443G8;?6@=129M675H51;1E?>5A3118J6743G99?6@<329M7157=;O60?K27;2D?=>5A4318J1543G>??6@;739M17=I>;1E;?5A829M<44IL92Z?7]O]T`9SMKYE]ZCOTo5_IO]AQVHFELo0^LCM17]P5=YT91;87^GB_BMOHLUNGGUHDHMD6:QLQWEB?2YYZLBPA69PVSGKWK>0_^\N4:QPVG2<\PZN8>5Z0.`ooZkbeVmnbh|ntnp,rdjnl'ixx!}alnlku]7U'xja#| v3,qeh)cx82s=5 }al60?P6(jeaTahcPgdlfvdrhz&|j`dj!crvq+wgjdfe{W8y3;*wgji2_XI_QNLHCPg>STM[U]E^GMLD18RFE>3_CN[RZVPD18S@G43^OIn6Y]IUG\BLTT\j1\^DZJ_LMGAZGd3^XBXHQBOEG\F4b^c`VZye`Xjrrklj46#37ljkr`*;-==flmxj$4'7;`fgvd:7611jhi|n<0<;?dbczh69255ndepb868?3hno~l2;>99b`atf4<437ljkr`>5:==flmxj0:07;`fgvd:?6h1jhi|n<883:==flmxj0407;`fgvg.7!11jhi|m(0+;?dbczk"9%55ndepa,6/?3hno~o&;)99b`ate <#37ljkrc*5-==flmxi$:'7;`fgvg.?!11jhi|m(8+;?dbczk6;255ndepa848?3hno~o2=>99b`ate4:437ljkrc>7:==flmxi0807;`fgvg:1611jhi|m<6<;?dbczk632l5ndepa8<<7611jhi|m<8<1b>dkcVgnaRijn^t2[4*'P`fbbu.LOSG#C`hbzh~d~-??.0,3767'7;ekme-73!11oeco'14+;?aoii!;=%55kioc+52/?3mcem%?7)99gmkg/90#<7igaa)0*<>bnfh"9<$64dhlb,77.02nbbl&=2(:8`lhf ;9"46jfn`*10,> 20hd`n(35*<>bnfh"94$64dhlb,7?.?2nbbl&<)99gmkg/;9#37igaa)12-2=cagk#8$94dhlb,0/03mcem%8&7:fjjd.0!>1oeco'8(58`lhf 0#<7igaa=2=<>bnfh6:<364dhlb847902nbbl2>2?:8`lhf489546jfn`>20;>720hd`n<05=<>bnfh6:4364dhlb84?9?2nbbl2>>99gmkg;:9437igaa=02:==cagk7>?07;ekme944611oeco325<;?aoii58>255kioc?638?3mcem1<8>99gmkg;:1437igaa=0::2=cagk7>364dhlb8669i2nbbl2<1;2=<>bnfh68=394dhlb86803mcem1:17:fjjd:26>1oeco36?58`lhf4>4<7igaa=:=3>bnfh622:5kio`+4,1bnfk"98$64dhla,73.02nbbo&=6(:8`lhe ;="46jfnc*1<,>bh}}k#=>'6;emvpd.6< 30hb{{a)36-<=cg|~j$<8&9:flqqg/9>#27iazt`*2<,?)89gkprf ;8"56j`uuc+66/>3me~xl&=4(;8`jssi!8>%45kotvb,70.12ndyyo'26+:?air|h"94$74dnwwe-4>!11ocxzn(2+:?air|h"8<$74dnwwe-56!11ocxzn(5+;?air|h">%55kotvb,3/?3me~xl&8)99gkprf 1#37iazt`*:-==cg|~j0=0m;emvpd:493:546j`uu`+4,>3me~xo&>5(;8`jssj!;=%45kotva,41.12ndyyl'19+:?air|k":5$64dnwwf-4.12ndyyl'21+:?air|k"9=$74dnwwf-45!01ocxzm(31*=>bh}}h#>9'6;emvpg.5= 30hb{{b)05-<=cg|~i$?9&9:flqqd/:1#27iaztc*1=,>bh}}h#;$64dnwwf->.02ndyyl'9(:8`jssj5:556j`uu`?558>3me~xo2>1?;8`jssj5;9245kotva845912ndyyl315<:?air|k6:9374dnwwf971601ocxzm<05==>bh}}h7=506;emvpg:61720hb{{b=3==>bh}}h7>=06;emvpg:59730hb{{b=01:<=cg|~i0?=19:flqqd;:=427iaztc>11;?89gkpre4;=556j`uu`?6=8>3me~xo2=9?:8`jssj58556j`uu`?758e3me~xo2<1;2==>bh}}h7?<07;emvpg:4611ocxzm<5<;?air|k6>255kotva838?3me~xo28>99gkpre41437iaztc>::g=cx{kf:?:w3305?avuid<98u==,cnh[hcjWnoeS{?P1-LLJ@*IGGO9j85kpscn272;;&i`fQbel]dakYq9V;'wnQgar]qabebj4:'oRfns^pfcfcf59&hS`kb_u{sa87+kVbjRczx^mvpussW{ol0>#c^rqmhYsqyo6=!mPshljpdYqie7; nQ}e`f\slbs`Vh6??"l_sgb`Zqnl}bTm0==,b]gmvgedlU|m`Pbit\gjjk59&hSd`ft^djh`Yiido6h}|nm707|64)e`l'oRy}iug\ijbbWk7\^DZJ_GKQWQ*dW~xbxhQboeg\e8QUA]OTJD\\T-a\hjgcW`dbxRhfld?2(fYpz`~nSikti]a9343$jU|~dzj_egspmYf5?8? nQgar]pwwd:8%iTdl}Psrpb95*dWhno~lQxievk946+kVkohlPwhfwl877$jUoikozlu]geqg:8%iTmai`rhvki87+kVnbllce^ubvkYe`Uymcij=1.`[mgtWdofSb{{ptv\v`at59&hSz|ftd]tmaroWk78>!mPwskwaZqnl}bTm0==,b]qadbXllzdRl2636/gZtbimUoi}zg_`?561*dWksiR}fzd?:(fYtadUhcabfshmm[fnbkb7J@A"l_bmnijhXkea65)eX`hyTico20-a\wlhn|kU}ma3?,bmntjhbf}Uem`k2dqpbi343p:8'oR{|e^`zp`Ypmk7; nQzsd]a}qcXlk633`47c<5?m9hwc?n9;38j4gf2=1/=l951`08yV>32;k96<75120a36`=:>n8o6]>2b81e0<72899n:=i:35g7a=T0=09m84?:011f25a2;=o?i5k28g94?7=9rY3:7455j>9m6?9k3b9uP4?6290:6<4:9zQ;2?4f:3;26<==b61e>71c;j1/=4m513f8R4g?2;q~=?k51:w26c<73t.:4n4;b:`1=`<72<=1?7;8{I3:e>\0m3?p?>4>d;3f>1?=3;o96g=a`83>!7?m38jn6`>8e83?>o6j=0;6)?7e;3aa>h60m0;76g>b283>!7?m3;ii6`>8e82?>o6j;0;6)?7e;3aa>h60m0976g>b083>!7?m3;ii6`>8e80?>o6j90;6)?7e;3aa>h60m0?76g>ag83>!7?m3;ii6`>8e86?>o6il0;6)?7e;3aa>h60m0=76g>ae83>!7?m3;ii6`>8e84?>o6ij0;6)?7e;3aa>h60m0376g>ac83>!7?m3;ii6`>8e8:?>o6k00;6)?7e;3g7>h60m0;76g>c983>!7?m3;o?6`>8e82?>o6k>0;6)?7e;3g7>h60m0976g>c783>!7?m3;o?6`>8e80?>o6k<0;6)?7e;3g7>h60m0?76g>c583>!7?m3;o?6`>8e86?>o6k:0;6)?7e;3g7>h60m0=76g>c383>!7?m3;o?6`>8e84?>o6k80;6)?7e;3g7>h60m0376g>c183>!7?m3;o?6`>8e8:?>i5??0;6)?7e;0:1>h60m0;76a=7483>!7?m38296`>8e82?>i5?:0;6)?7e;0:1>h60m0976a=7383>!7?m38296`>8e80?>i5?80;6)?7e;0:1>h60m0?76a=7183>!7?m38296`>8e86?>i5>o0;6)?7e;0:1>h60m0=76a=6d83>!7?m38296`>8e84?>i5>m0;6)?7e;0:1>h60m0376a=6b83>!7?m38296`>8e8:?>i5>k0;6)?7e;0:1>h60m0j76a=6`83>!7?m38296`>8e8a?>i5>10;6)?7e;0:1>h60m0h76a=6683>!7?m38296`>8e8g?>i5>?0;6)?7e;0:1>h60m0n76a=6483>!7?m38296`>8e8e?>i5>=0;6)?7e;0:1>h60m0:<65`27194?"60l09585a19f954==2d:4i4>4:9l60`=83.:4h4=949m5=b=9<10c?9l:18'5=c=:0?0b<6k:048?j40j3:1(<6j:3;6?k7?l3;<76a=7`83>!7?m38296`>8e82<>=h:>31<7*>8d81=0=i91n1=454o35;>5<#91o1>4;4n0:g>4g<3f8<;7>5$0:f>7?23g;3h7?m;:m131<72-;3i7<65:l2;750;&2<`<51<1e=5j51e98k73b290/=5k52878j4>c28o07b<:d;29 4>b2;3>7c?7d;3e?>o6l>0;66g>d983>>o6n;0;6)?7e;025>h60m0;76g>f083>!7?m38:=6`>8e82?>o6mo0;6)?7e;025>h60m0976g>ed83>!7?m38:=6`>8e80?>o6mm0;6)?7e;025>h60m0?76g>eb83>!7?m38:=6`>8e86?>o6mk0;6)?7e;025>h60m0=76g>e`83>!7?m38:=6`>8e84?>o6m00;6)?7e;025>h60m0376g>e983>!7?m38:=6`>8e8:?>o6m>0;6)?7e;025>h60m0j76g>e783>!7?m38:=6`>8e8a?>o6m=0;6)?7e;025>h60m0h76g>e283>!7?m38:=6`>8e8g?>o6m;0;6)?7e;025>h60m0n76g>e083>!7?m38:=6`>8e8e?>o6m90;6)?7e;025>h60m0:<65f1ed94?"60l09=<5a19f954=;o3;`?7432c:hn4?:%3;a?4692d:4i4>4:9j5ad=83.:4h4=109m5=b=9<10ef783>!7?m38:=6`>8e82<>=n9o?1<7*>8d8154=i91n1=454i0d7>5<#91o1>4g<3`;m?7>5$0:f>7763g;3h7?m;:k2b5<72-;3i7<>1:l2c28o07d?k9;29 4>b2;;:7c?7d;3e?>d61k0;6<4?:1yK551;294~N61h1/=485e09la5<722wi;i4?:8g90?3>sA;2m6T8e;3365=;=0:h7?j:5:90<<3>3><696548807?5328n1=h4;6;64>x"61?09m<5+8081=c=#0<09m=5+19:95=g5<5<5<5<#91o1>lk4n0:g>5=5<#91o1=ok4n0:g>4=5<#91o1=ok4n0:g>6=5<#91o1=ok4n0:g>0=5<#91o1=ok4n0:g>2=5<#91o1=ok4n0:g><=5<#91o1=i=4n0:g>4=5<#91o1=i=4n0:g>6=6=4+19g95a55<#91o1=i=4n0:g>0=5<#91o1=i=4n0:g>2=5<#91o1=i=4n0:g><=5<#91o1>8m4n0:g>4=5<#91o1>8m4n0:g>6=m6=4+19g960e5<#91o1>8m4n0:g>0=o6=4+19g960e5<#91o1>8m4n0:g>2=i6=4+19g960e5<#91o1>8m4n0:g><=26=4+19g960e5<#91o1>8m4n0:g>g==6=4+19g960e5<#91o1>8m4n0:g>a=?6=4+19g960e5<#91o1>8m4n0:g>c=96=4+19g960e4;n075?6=,82n6?;l;o3;`?7632e98=4?:%3;a?42k2d:4i4>2:9l66`=83.:4h4=5b9m5=b=9:10c?=j:18'5=c=:76a=5`83>!7?m38>o6`>8e822>=h:<31<7*>8d811f=i91n1=:54o37;>5<#91o1>8m4n0:g>4><3f8>;7>5$0:f>73d3g;3h7?6;:m113<72-;3i7<:c:l28;50;&2<`<5=j1e=5j51c98k735290/=5k524a8j4>c28i07b<;7;29 4>b2;?h7c?7d;3g?>i5;j0;6)?7e;06g>h60m0:i65`22`94?"60l099n5a19f95c=5<#91o1>4;4n0:g>4=5<#91o1>4;4n0:g>6=5<#91o1>4;4n0:g>0=5<#91o1>4;4n0:g>2=5<#91o1>4;4n0:g><=5<#91o1>4;4n0:g>g=5<#91o1>4;4n0:g>a=5<#91o1>4;4n0:g>c=4;n057?6=,82n6?7:;o3;`?7632e9:?4?:%3;a?4>=2d:4i4>2:9l637=83.:4h4=949m5=b=9:10c?8?:18'5=c=:0?0b<6k:068?j42n3:1(<6j:3;6?k7?l3;>76a=7b83>!7?m38296`>8e822>=h:>h1<7*>8d81=0=i91n1=:54o35b>5<#91o1>4;4n0:g>4><3f8<57>5$0:f>7?23g;3h7?6;:m13=<72-;3i7<65:l2:950;&2<`<51<1e=5j51c98k713290/=5k52878j4>c28i07b<99;29 4>b2;3>7c?7d;3g?>i5=l0;6)?7e;0:1>h60m0:i65`24f94?"60l09585a19f95c=5<5<#91o1>4=5<#91o1>6=5<#91o1>0=5<#91o1>2=5<#91o1><=5<#91o1>g=5<#91o1>a=5<#91o1>c=4;h3gb?6=,82n6??>;o3;`?7632c:hh4?:%3;a?4692d:4i4>2:9j5ab=83.:4h4=109m5=b=9:10e76g>f983>!7?m38:=6`>8e822>=n9o=1<7*>8d8154=i91n1=:54i0d5>5<#91o1>4><3`;m97>5$0:f>7763g;3h7?6;:k2b1<72-;3i7<>1:l2c28i07d?j5;29 4>b2;;:7c?7d;3g?>o6lh0;6)?7e;025>h60m0:i65f1e;94?"60l09=<5a19f95c=5<#91o1>>o4n0:g>4=5<#91o1>>o4n0:g>6=5<#91o1>>o4n0:g>0=5<#91o1>>o4n0:g>2=5<#91o1>>o4n0:g><=5<#91o1>>o4n0:g>g=6=4+19g966g5<#91o1>>o4n0:g>a=5<#91o1>>o4n0:g>c=4;h014?6=,82n6?=n;o3;`?7632c9=k4?:%3;a?44i2d:4i4>2:9j64c=83.:4h4=3`9m5=b=9:10e??k:18'5=c=::k0b<6k:068?l46k3:1(<6j:31b?k7?l3;>76g=3883>!7?m388m6`>8e822>=n::21<7*>8d817d=i91n1=:54i314>5<#91o1>>o4n0:g>4><3`88:7>5$0:f>75f3g;3h7?6;:k170<72-;3i7<>:50;&2<`<5;h1e=5j51c98m756290/=5k522c8j4>c28i07d<=6;29 4>b2;9j7c?7d;3g?>o59k0;6)?7e;00e>h60m0:i65f20c94?"60l09?l5a19f95c=:183!7>>3o:7E?n3:J2=d=hm90;66sm1`794?7=83:p(<79:0;a?M7f;2B:5l5`19`94?=zj8336=494;294~"61?0:4k5G1`18L4?f3S=n6lu>b;3`>7d=:j0?=7:=:3f906<5m3>?6p*>2981?!751380(h<51`9'a6<292.n87<:;%g6>7><,l<1?6*j7;08 4?5281/=4=51:&fe?4>3-oi6>k4$da96d=#mm08m6*je;16?!ca2890(k>5319'b4<592.m>7j4$g1974=#n=0=7)h::368 c0=;>1/j:4m;%d;>60<,o31?o5+f`82<>"aj3;=7)hl:69'ba<5;2.mi7=6;%de>6><,8:;6<>4$022>44<,8:96h5+111951=#99>1m6*>04821>"68?09>6*>06825>"6810h7)??9;05?!77i320(<>m:058 46d2;=0(<>k:0d8 46b2;:0(<>i:g9'546==2.:=<4=;%326?4<,8;86?5+10696>"69<097)?>6;08 4702;1/=<652:&25<<53-;:m7<4$03a>7=#98i1>6*>1e81?!76m380(<4=;%316?4<,8886?5+13696>"6:<097)?=6;08 4402;1/=l?518d8 `>=:2.:5=48b:&26d<63-;9n7?4$0c3>4?a3-o26?5f8383>>o?;3:17djk:188mac=831b=4:50;9j5<3=831b=4j50;9j54;h4`>5<#91o1:i5a19f95>=n>k0;6)?7e;4g?k7?l3807d8n:18'5=c=>m1e=5j53:9j2<<72-;3i78k;o3;`?2<3`<36=4+19g92a=i91n1965f6683>!7?m35<#91o1:i5a19f9=>=n?00;6)?7e;5;?k7?l3:07d98:18'5=c=?11e=5j51:9j33<72-;3i797;o3;`?4<3`=>6=4+19g93==i91n1?65f7583>!7?m3=37c?7d;68?l14290/=5k5799m5=b==21b;?4?:%3;a?1?3g;3h784;h52>5<#91o1;55a19f93>=n?90;6)?7e;5;?k7?l3207d8i:18'5=c=?11e=5j59:9j=4<72-;3i77?;o3;`?6<3`2m6=4+19g9=5=i91n1=65f8d83>!7?m33;7c?7d;08?l>c290/=5k5919m5=b=;21b4n4?:%3;a??73g;3h7:4;h:a>5<#91o15=5a19f91>=n1h0;6)?7e;;3?k7?l3<07d76:18'5=c=191e=5j57:9j==<72-;3i77?;o3;`?><3`3<6=4+19g9=5=i91n1565f9783>!7?m33;7c?7d;c8?l?2290/=5k5919m5=b=j21b594?:%3;a??73g;3h7m4;h;0>5<#91o15=5a19f9`>=n1;0;6)?7e;;3?k7?l3o07d6n:18'5=c=191e=5j5f:9je7<72-;3i7o>;o3;`?6<3`k;6=4+19g9e4=i91n1=65f9g83>!7?m3k:7c?7d;08?l?b290/=5k5a09m5=b=;21b5i4?:%3;a?g63g;3h7:4;h;`>5<#91o1m<5a19f91>=nik0;6)?7e;c2?k7?l3<07don:18'5=c=i81e=5j57:9je<<72-;3i7o>;o3;`?><3`k36=4+19g9e4=i91n1565fa683>!7?m3k:7c?7d;c8?lg1290/=5k5a09m5=b=j21bm84?:%3;a?g63g;3h7m4;hc7>5<#91o1m<5a19f9`>=ni:0;6)?7e;c2?k7?l3o07d7m:18'5=c=i81e=5j5f:9je`<72-;3i7ok;o3;`?6<3`kh6=4+19g9ea=i91n1=65fb083>!7?m3h;7c?7d;28?lga290/=5k5b19m5=b=921dn44?:%3;a?d?3g;3h7>4;n`4>5<#91o1n55a19f95>=hj?0;6)?7e;`;?k7?l3807bl::18'5=c=j11e=5j53:9lf1<72-;3i7l7;o3;`?2<3fh86=4+19g9f==i91n1965`c383>!7?m3h37c?7d;48?je6290/=5k5b99m5=b=?21do=4?:%3;a?d?3g;3h764;n`e>5<#91o1n55a19f9=>=hjl0;6)?7e;`;?k7?l3k07blk:18'5=c=j11e=5j5b:9lff<72-;3i7l7;o3;`?e<3fhi6=4+19g9f==i91n1h65`b`83>!7?m3h37c?7d;g8?jd5290/=5k5b99m5=b=n21dh;4?:%3;a?b23g;3h7>4;nf7>5<#91o1h85a19f95>=hkh0;6)?7e;a:?k7?l3:07bm7:18'5=c=k01e=5j51:9lg2<72-;3i7m6;o3;`?4<3fi=6=4+19g9g<=i91n1?65`c483>!7?m3i27c?7d;68?je3290/=5k5c89m5=b==21dh>4?:%3;a?e>3g;3h784;nf1>5<#91o1o45a19f93>=hl80;6)?7e;a:?k7?l3207bj?:18'5=c=k01e=5j59:9lgc<72-;3i7m6;o3;`?g<3fin6=4+19g9g<=i91n1n65`ce83>!7?m3i27c?7d;a8?jed290/=5k5c89m5=b=l21doo4?:%3;a?e>3g;3h7k4;na0>5<#91o1o45a19f9b>=hl00;6)?7e;f;?k7?l3:07bj8:18'5=c=l11e=5j51:9~f4?0290=87>50z&2=3<60o1C=l=4H0;b?_1b2hq:n7?l:3`96f<393>96?j54281a?232t.:>54=;%31=?4<,l81?n5+e28:?!c32=i0(h;5449'a3<33-o<6?5+18095>"61:0:7)kn:428 `d=011/in4:d:&f`?3>3-on6;<4$dd90a=#n90on6*i1;7;?!`52=:0(k=53g9'b1<0k2.m97ji;%d5>1g<,o=1hl5+f986g>"a13?97)hn:2f8 cd=5+111913=#99>1:>5+117977=#99<19l5+1159<<=#99219h5+11;96c=#99k1;l5+11`9<5=#99i14:5+11f91c=#99o1:<5+11d911=#98:19:5+10396>"69;097)?>3;08 4732;1/=<;52:&253<53-;:;7<4$03;>7=#9831>6*>1`81?!76j380("6:;097)?=3;08 4432;1/=?;52:&263<53-;9;7<4$0c2>4?a3-o36?5+18293g=#9;k1=6*>2c82?!7f83;2j6*j9;08m=4=831b4>4?::kg`?6=3`nn6=44i0;7>5<6=44i0;g>5<8e83?>o1k3:1(<6j:7f8j4>c2810e;l50;&2<`<1l2d:4i4=;:k5e?6=,82n6;j4n0:g>6=8d85`>h60m0?76g98;29 4>b2?n0b<6k:498m31=83.:4h49d:l25$0:f>3b8e8;?>o1<3:1(<6j:7f8j4>c2010e:750;&2<`<002d:4i4?;:k43?6=,82n6:64n0:g>4=<1<7*>8d84<>h60m0976g85;29 4>b2>20b<6k:298m22=83.:4h488:l25$0:f>2>8e85?>o093:1(<6j:6:8j4>c2>10e:>50;&2<`<002d:4i47;:k5b?6=,82n6:64n0:g><=8d8:4>h60m0;76g7f;29 4>b20:0b<6k:098m=c=83.:4h460:l25$0:f><654i9a94?"60l02<6`>8e87?>o?j3:1(<6j:828j4>c2<10e4o50;&2<`<>82d:4i49;:k:=?6=,82n64>4n0:g>2=8d8:4>h60m0376g67;29 4>b20:0b<6k:898m<0=83.:4h460:l25$0:f><68e8`?>o>;3:1(<6j:828j4>c2m10e4<50;&2<`<>82d:4i4j;:k;e?6=,82n64>4n0:g>c=8d8b5>h60m0;76gn0;29 4>b2h;0b<6k:098m<`=83.:4h4n1:l25$0:f>d754i8f94?"60l0j=6`>8e87?>o>k3:1(<6j:`38j4>c2<10ell50;&2<`2=8d8b5>h60m0376gn8;29 4>b2h;0b<6k:898md1=83.:4h4n1:l25$0:f>d78e8`?>of<3:1(<6j:`38j4>c2m10el=50;&2<`c=8d8b`>h60m0;76gnc;29 4>b2hn0b<6k:098mg7=83.:4h4m0:l25$0:f>g68e83?>ie?3:1(<6j:c:8j4>c2810co850;&2<`6=1<7*>8d8a<>h60m0?76am3;29 4>b2k20b<6k:498kf4=83.:4h4m8:l25$0:f>g>8e8;?>ien3:1(<6j:c:8j4>c2010cok50;&2<`g=8d8a<>h60m0h76amb;29 4>b2k20b<6k:e98kgg=83.:4h4m8:l27>5$0:f>g>8e83?>ic<3:1(<6j:e78j4>c2810cno50;&2<`4=8d8`=>h60m0976al6;29 4>b2j30b<6k:298kf3=83.:4h4l9:l25$0:f>f?8e85?>ic:3:1(<6j:b;8j4>c2>10ci?50;&2<`<=8d8`=>h60m0j76ale;29 4>b2j30b<6k:c98kfb=83.:4h4l9:l25$0:f>f?8e8f?>id;3:1(<6j:b;8j4>c2o10ci750;&2<`4=53z\2`2=:90214?521859<7=z{8n36=4<{_3g<>;61103?63>968;7>{t:X5=:1U>8?4^373?[43n2T98h5Q25f8Z72d3W8?n6P=4`9]61?37S<;6:\100=Y:=>0R?:<;_076>X5<81U>9>4^31e?[44m2T9?i5Q24c8Z73>3W8>46P=569]6007S<:2:\102=Y::i0R?=m;<3b0?c734;247?64:?2==<61<16=46518g894??20;01<77:9d894??21o01<77:`0894??2h:01<77:8d894??20o01<77:8f894??20i01<77:``894??2hk01<77:`;894??2h201<77:`5894??2h<01<77:`7894??2h>01<77:`1894??20h01<77:`g894??2k;01<77:`d894?0283?70?67;3:1>;61>0:5h521859e7=:90=1m=521859=c=:90=15h521859=a=:90=15n521859eg=:90=1ml521859e<=:90=1m5521859e2=:90=1m;521859e0=:90=1m9521859e6=:90=15o521859f4=:90=1mk5rs3;5>5<5sW8<:63>998`2>{t:0>1<703i>7p}=9383>7}Y:>901<77:b68yv4>93:1>vP=739>5<>=l:1v?7?:181[40927:554k2:p6=`=838pR?9?;<3:;6110hj6s|29`94?4|V;h16=465cb9~w7>02909wS<98:?2==5850;0xZ70034;247m<;|q1<0<72;qU>;84=0;4>a?52z\120=:90=1ol5rs3:0>5<5sW8=863>968`<>{t:181<7?3i<7p}=8083>7}Y:?801<78:b48yv4?83:1>vP=609>5<1=k<1v?9i:181[41827:5:4l4:p62c=838pR?;i;<3:3?b43ty95i4?:3y]62e<583<6i<4}r0:g?6=:rT9;o521859`2=z{;3i6=4={_04e>;61>0o=6s|28c94?4|V;=270?67;f3?xu5100;6?uQ26:894?02jl0q~<68;296~X5?>16=495cd9~w7?02909wS<84:?2=24=50;0xZ70>34;2;7ml;|q1<=<72;qU>8k4=0;4>fd52z\11a=:90=1o>5rs3c`>5<4sW8jm63>9982=a=:90=1=4j4}r3ab?6=;rT:n95218:92`=:90=1:h5rs0`g>5<4sW;i?63>9985g>;61>0=o6s|1ca94?5|V8h970?68;4a?87>?3bc83>6}Y9k;01<77:7c894?02?k0q~?ma;297~X6j916=465689>5<1=>01v3053z\2ef=:9021:852185920=z{8h>6=4<{_3bf>;6110=863>96850>{t9m>1<7=t^0a:?87>03=270?67;5:?xu6l;0;6>uQ1b:894??2>=01<78:658yv7c93:1?vP>c69>5<>=??16=495779~w4b72908wS?l6:?2==<0=27:5:485:p5f`=839pR25<583<6:=4}r3``?6=;rT:o>5218:937=:90=1;?5rs0a`>5<4sW;h>63>99845>;61>0<=6s|1b`94?5|V8i:70?68;53?87>?3=;7p}>c`83>6}Y9j:01<77:7d894?02?l0q~<>2;296~X6n;16=4658e9~w7772909wS?i1:?2===k50;0xZ4ca34;2476m;|q14a<72;qU=hk4=0;;>52z\2aa=:9021545rs32a>5<5sW;no63>998bg>{t:9k1<703337p}=0883>7}Y9lk01<77:858yv4703:1>vP>e89>5<>=1?1v?>8:181[7b027:55465:p650=838pR;61103m6s|21394?4|V8o970?67;cf?xu5890;6?uQ1d3894?020;0q~?if;296~X6m916=4958g9~w4`b2909wS?kf:?2=2=e52z\2`f=:90=14o5rs0db>5<5sW;on63>968:e>{t:831<7?3327p}=1983>7}Y9o=01<78:`a8yv46?3:1>vP>f79>5<1=111v??9:181[7a=27:5:467:p643=838pR;61>02?6s|21694?4|V8nj70?67;;1?xu6n00;6?uQ1e;894?021k0q~?<0;291~;6i<0:4o5218:9`a=:9021hh521859`a=:90=1hh5r}r3g3?6=:rT:h:527e82`2=#9031=;;4}r026?6=:rT:j?527e82b7=#9031=:>4}r024?6=:rT:j<527e82b4=#9031=:l4}r03a?6=:rT:ik527e82ac=#9031=5<4}r03`?6=:rT:ih527e82a`=#9031=5=4}r03g?6=:rT:ii527e82aa=#9031=5:4}r03f?6=:rT:in527e82af=#9031=5;4}r03e?6=:rT:io527e82ag=#9031=594}r03=?6=:rT:il527e82ad=#9031=>?4}r03<4}r033?6=:rT:i5527e82a==#9031=>74}r032?6=:rT:i:527e82a2=#9031=9>4}r031?6=:rT:i;527e82a3=#9031=9l4}r037?6=:rT:i9527e82a1=#9031=884}r036?6=:rT:i>527e82a6=#9031=;?4}r035?6=:rT:i?527e82a7=#9031=;<4}r034?6=:rT:i<527e82a4=#9031=;=4}r3eb?6=:rT:i=527e82a5=#9031=;:4}r3ea?6=:rT:hk527e82`c=#9031=;84}r3e`?6=:rT:hh527e82``=#9031=;94}r3eg?6=:rT:hi527e82`a=#9031=;64}r3ef?6=:rT:hn527e82`f=#9031=;74}r3ee?6=:rT:ho527e82`g=#9031=;o4}r02=?6=:rT:j5527e82b==#9031=;l4}r02527e82b6=#9031=:?4}r027?6=:rT:j=527e82b5=#9031=:<4}r03b?6=:rT:i8527e82a0=#9031=:=4}r030?6=:rT:hl527e82`d=#9031=::4}r3e=?6=:rT:h4527e82`<=#9031=:;4}r3ab?6=:rT:n9527e82f1=#9031=:84}r3a`?6=:rT:n>527e82f6=#9031=:94}r3ag?6=:rT:n?527e82f7=#9031=:64}r3af?6=:rT:n<527e82f4=#9031=:74}r3ae?6=:rT:n=527e82f5=#9031=:o4}r3a=?6=:rT:mk527e82ec=#9031=:m4}r3a4}r0bg?6=:rT9ml527e81ed=#9031=5?4}r3g=4}r3g6?6=:rT:o5527e82g==#9031=>:4}r3g5?6=:rT:o:527e82g2=#9031=>;4}r3g4?6=:rT:o;527e82g3=#9031=>84}r3`b?6=:rT:o8527e82g0=#9031=>94}r3`a?6=:rT:o9527e82g1=#9031=>64}r3``?6=:rT:o>527e82g6=#9031=>o4}r3`g?6=:rT:o?527e82g7=#9031=>l4}r3`f?6=:rT:o<527e82g4=#9031=>m4}r3`e?6=:rT:o=527e82g5=#9031=>j4}r0:2?6=:rT9;;527e8133=#9031=>k4}r0:0?6=:rT9;8527e8130=#9031=>h4}r0:6?6=:rT9;>527e8136=#9031=9?4}r0:5?6=:rT9;?527e8137=#9031=9<4}r0:4?6=:rT9;<527e8134=#9031=9=4}r0;b?6=:rT9;=527e8135=#9031=9:4}r0;a?6=:rT9:k527e812c=#9031=9;4}r0;`?6=:rT9:h527e812`=#9031=984}r0;g?6=:rT9:i527e812a=#9031=994}r0;f?6=:rT9:n527e812f=#9031=964}r0;e?6=:rT9:o527e812g=#9031=974}r0;=?6=:rT9:l527e812d=#9031=9o4}r0;3?6=:rT9:5527e812==#9031=9m4}r0;2?6=:rT9::527e8122=#9031=9j4}r0;1?6=:rT9:;527e8123=#9031=9k4}r0;0?6=:rT9:8527e8120=#9031=9h4}r0;7?6=:rT9:9527e8121=#9031=8>4}r0;6?6=:rT9:>527e8126=#9031=8?4}r0;5?6=:rT9:?527e8127=#9031=8<4}r0;4?6=:rT9:<527e8124=#9031=8=4}r04b?6=:rT9:=527e8125=#9031=8:4}r04a?6=:rT99k527e811c=#9031=8;4}r0:`?6=:rT9;n527e813f=#9031=894}r0:g?6=:rT9;o527e813g=#9031=864}r0:f?6=:rT9;l527e813d=#9031=874}r0:e?6=:rT9;4527e813<=#9031=8o4}r0:=?6=:rT9;5527e813==#9031=8l4}r0:4}|l16f<72;qC=4o4}o01`?6=:rB:5l5rn30f>5<5sA;2m6sa23d94?4|@83j7p`=3183>7}O90k0qc<<1;296~N61h1vb?==:181M7>i2we>>=50;0xL4?f3td9?94?:3yK552zJ2=d=zf;9=6=4={I3:e>{i::=1<7vF>9`9~j75f2909wE?6a:m66d=838pD<7n;|l17f<72;qC=4o4}o00`?6=:rB:5l5rn31f>5<5sA;2m6sa22d94?4|@83j7p`=4183>7}O90k0qc<;1;296~N61h1vb?:=:181M7>i2we>9=50;0xL4?f3td9894?:3yK552zJ2=d=zf;>=6=4={I3:e>{i:==1<7vF>9`9~j72f2909wE?6a:m61d=838pD<7n;|l10f<72;qC=4o4}o07`?6=:rB:5l5rn36f>5<5sA;2m6sa25d94?4|@83j7p`=5183>7}O90k0qc<:1;296~N61h1vb?;=:181M7>i2we>8=50;0xL4?f3td9994?:3yK597>52zJ2=d=zf;?=6=4={I3:e>{i:<=1<7vF>9`9~j73f2909wE?6a:m60d=838pD<7n;|l11f<72;qC=4o4}o06`?6=:rB:5l5rn37f>5<5sA;2m6sa24d94?4|@83j7p`=6183>7}O90k0qc<91;296~N61h1vb?8=:181M7>i2we>;=50;0xL4?f3td9:94?:3yK552zJ2=d=zf;<=6=4={I3:e>{i:?=1<710;6?uG18c8yk4113:1>vF>9`9~j70f2909wE?6a:m63d=838pD<7n;|l12f<72;qC=4o4}o05`?6=:rB:5l5rn34f>5<5sA;2m6sa27d94?4|@83j7p`=7183>7}O90k0qc<81;296~N61h1vb?9=:181M7>i2we>:=50;0xL4?f3td9;94?:3yK552zJ2=d=zf;==6=4={I3:e>{i:>=1<7vF>9`9~j71f2909wE?6a:m62d=838pD<7n;|l13f<72;qC=4o4}o04`?6=:rB:5l5rn35f>5<5sA;2m6sa26d94?4|@83j7p`=8183>7}O90k0qc<71;296~N61h1vb?6=:181M7>i2we=i;50;3xL4?f3td9>o4?:0yK5" LOC = "P90"; +NET "addr<11>" LOC = "P91"; +NET "addr<10>" LOC = "P85"; +NET "addr<9>" LOC = "P92"; +NET "addr<8>" LOC = "P94"; +NET "addr<7>" LOC = "P95"; +NET "addr<6>" LOC = "P98"; +NET "addr<5>" LOC = "P3"; +NET "addr<4>" LOC = "P2"; +NET "addr<3>" LOC = "P78"; +NET "addr<2>" LOC = "P79"; +NET "addr<1>" LOC = "P83"; +NET "addr<0>" LOC = "P84"; + +#DATA BUS +NET "sram_data<7>" LOC = "P4"; +NET "sram_data<6>" LOC = "P5"; +NET "sram_data<5>" LOC = "P9"; +NET "sram_data<4>" LOC = "P10"; +NET "sram_data<3>" LOC = "P11"; +NET "sram_data<2>" LOC = "P12"; +NET "sram_data<1>" LOC = "P15"; +NET "sram_data<0>" LOC = "P16"; + +#CONTROL BUS +NET "nwe" LOC = "P88"; +NET "noe" LOC = "P86"; +NET "ncs" LOC = "P69"; + + diff --git a/Examples/ehw4/logic/ehw.v b/Examples/ehw4/logic/ehw.v new file mode 100644 index 0000000..d6fa350 --- /dev/null +++ b/Examples/ehw4/logic/ehw.v @@ -0,0 +1,278 @@ +`timescale 1ns / 1ps +module ehw(clk, sram_data, addr, nwe, ncs, noe, reset, led, + irq_pin); + + parameter B = (7); + + input clk, addr, nwe, ncs, noe, reset; + inout [B:0] sram_data; + output led; + output irq_pin; + + // synchronize signals + reg sncs, snwe; + reg [12:0] buffer_addr; + reg [B:0] buffer_data; + wire led; + + // bram-cpu interfaz + reg we; + reg w_st=0; + reg [B:0] wdBus; + reg [B:0] rdBus; + wire [12:0] addr; + reg [7:0] bae; + + + // bram-evalfit interfaz + wire we_eval, en_ev; + wire [63:0] ev_do; + wire [63:0] ev_di; + + // Interconnection + wire [31:0] mt_rnd; + wire [31:0] reg0; + wire [31:0] reg1; + wire [31:0] reg2; + wire [31:0] reg3; + wire [31:0] reg4; + wire [7:0] status; + wire [15:0] error; + wire [8:0] evalfit_addr; + + wire en_fit; + wire [15:0] max_com; + wire [3:0] max_lev; + wire [7:0] control; + + reg [7:0] reg_bank [31:0]; + wire enReg; + wire [4:0] address; + +// Test : LED blinking + reg [25:0] counter; + always @(posedge clk) begin + if (~reset) + counter <= {25{1'b0}}; + else + counter <= counter + 1; + end + assign led = counter[24]; + +// Data Bus direction control + wire T = ~noe | ncs; + assign sram_data = T?8'bZ:rdBus; + +// synchronize assignment + always @(negedge clk) + begin + sncs <= ncs; + snwe <= nwe; + buffer_data <= sram_data; + buffer_addr <= addr; + end + +// write access cpu to bram + always @(posedge clk) + if(~reset) {w_st, we, wdBus} <= 0; + else begin + wdBus <= buffer_data; + case (w_st) + 0: begin + we <= 0; + if(sncs | snwe) w_st <= 1; + end + 1: begin + if(~(sncs | snwe)) begin + we <= 1; + w_st <= 0; + end + else we <= 0; + end + endcase + end + + + // Address Decoder + // We have 2 memory blocks 1: 512 x 64 bits memory 32kb = 4kB 0000 - 0FFF buffer_addr[12] = 0 + // 2: Register Bank 1000 - 101F buffer_addr[12] = 1 + + // SIE has an eight bits data bus, this module generate the required signals to create a 64 bits word. + always @(buffer_addr) + begin + if(~buffer_addr[12]) begin + case (buffer_addr[2:0]) + 0: bae <= 8'h01; + 1: bae <= 8'h02; + 2: bae <= 8'h04; + 3: bae <= 8'h08; + 4: bae <= 8'h10; + 5: bae <= 8'h20; + 6: bae <= 8'h40; + 7: bae <= 8'h80; + endcase + end + else + bae <= 8'h00; + end + wire en1, en2; // enable memory signals + assign en0 = bae[0] | bae[1] | bae[2] | bae[3]; + assign en1 = bae[4] | bae[5] | bae[6] | bae[7]; + + reg[31:0] DIA_Aux; + always @ (posedge clk) begin + if (bae[0]) DIA_Aux[7:0] = wdBus[7:0]; + if (bae[1]) DIA_Aux[15:8] = wdBus[7:0]; + if (bae[2]) DIA_Aux[23:16] = wdBus[7:0]; + if (bae[3]) DIA_Aux[31:24] = wdBus[7:0]; + if (bae[4]) DIA_Aux[7:0] = wdBus[7:0]; + if (bae[5]) DIA_Aux[15:8] = wdBus[7:0]; + if (bae[6]) DIA_Aux[23:16] = wdBus[7:0]; + if (bae[7]) DIA_Aux[31:24] = wdBus[7:0]; + end + + reg [2:0] state, nextstate; //FSM for write in 32bit mode to memory + wire we0, we1; + wire nreset; + assign nreset = ~reset; + parameter S0 = 3'b000; + parameter S1 = 3'b001; + parameter S2 = 3'b010; + + always @ (posedge clk, posedge nreset) + if (nreset) state <= S0; + else state <= nextstate; + // next state logic + always@(*) + case (state) + S0:if (bae[3]&we) nextstate = S1; + else + if (bae[7]&we) nextstate = S2; + else nextstate = S0; + S1: nextstate = S0; + S2: nextstate = S0; + default: nextstate = S0; + endcase + // output logic + assign we0 = (state == S1); + assign we1 = (state == S2); + +// Read control + reg [7:0] MemDOA; + wire [63:0] DOA_Aux; + + always @(posedge clk) + if(~reset)begin + rdBus = 8'h00; + end + else begin + if(enReg) + rdBus = reg_bank[address]; + else + rdBus = MemDOA[7:0]; + end +// memory output mux + always @(buffer_addr[2:0]) + case (buffer_addr[2:0]) + 0 : MemDOA = DOA_Aux[7:0]; + 1 : MemDOA = DOA_Aux[15:8]; + 2 : MemDOA = DOA_Aux[23:16]; + 3 : MemDOA = DOA_Aux[31:24]; + 4 : MemDOA = DOA_Aux[39:32]; + 5 : MemDOA = DOA_Aux[47:40]; + 6 : MemDOA = DOA_Aux[55:48]; + 7 : MemDOA = DOA_Aux[63:56]; + default: MemDOA = 8'h00; + endcase + +// Store Inputs + always @(posedge clk) + begin + if(enReg) begin + reg_bank[20] = error[7:0]; + reg_bank[21] = error[15:8]; + reg_bank[22] = status[7:0]; + reg_bank[24] = mt_rnd[7:0]; + reg_bank[25] = mt_rnd[15:8]; + reg_bank[26] = mt_rnd[23:16]; + reg_bank[27] = mt_rnd[31:24]; + end + end + + assign address[4:0] = buffer_addr[4:0]; + assign enReg = buffer_addr[12]; + + assign reg0[7:0] = reg_bank[0]; + assign reg0[15:8] = reg_bank[1]; + assign reg0[23:16] = reg_bank[2]; + assign reg0[31:24] = reg_bank[3]; + assign reg1[7:0] = reg_bank[4]; + assign reg1[15:8] = reg_bank[5]; + assign reg1[23:16] = reg_bank[6]; + assign reg1[31:24] = reg_bank[7]; + assign reg2[7:0] = reg_bank[8]; + assign reg2[15:8] = reg_bank[9]; + assign reg2[23:16] = reg_bank[10]; + assign reg2[31:24] = reg_bank[11]; + assign reg3[7:0] = reg_bank[12]; + assign reg3[15:8] = reg_bank[13]; + assign reg3[23:16] = reg_bank[14]; + assign reg3[31:24] = reg_bank[15]; + assign reg4[7:0] = reg_bank[16]; + assign reg4[15:8] = reg_bank[17]; + assign reg4[23:16] = reg_bank[18]; + assign reg4[31:24] = reg_bank[19]; + + assign max_lev = reg_bank[28]; + assign control = reg_bank[29]; + assign max_com[7:0] = reg_bank[30]; + assign max_com[15:8] = reg_bank[31]; + // Write control + always @(negedge clk) + if(we & enReg) begin + case (address) + 0: reg_bank[0] = wdBus; + 1: reg_bank[1] = wdBus; + 2: reg_bank[2] = wdBus; + 3: reg_bank[3] = wdBus; + 4: reg_bank[4] = wdBus; + 5: reg_bank[5] = wdBus; + 6: reg_bank[6] = wdBus; + 7: reg_bank[7] = wdBus; + 8: reg_bank[8] = wdBus; + 9: reg_bank[9] = wdBus; + 10: reg_bank[10] = wdBus; + 11: reg_bank[11] = wdBus; + 12: reg_bank[12] = wdBus; + 13: reg_bank[13] = wdBus; + 14: reg_bank[14] = wdBus; + 15: reg_bank[15] = wdBus; + 16: reg_bank[16] = wdBus; + 17: reg_bank[17] = wdBus; + 18: reg_bank[18] = wdBus; + 19: reg_bank[19] = wdBus; + 28: reg_bank[28] = wdBus; + 29: reg_bank[29] = wdBus; + 30: reg_bank[30] = wdBus; + 31: reg_bank[31] = wdBus; + endcase + end + +RAMB16_S36_S36 #(.INIT_00(256'hABCDEF00_00000000_00000000_00000000_00000000_00000000_00000000_76543210) ) + mem0 ( .CLKA(~clk), .ENA(en0), .SSRA(1'b0), .ADDRA(buffer_addr[11:3]), .WEA(we0), .DIA(DIA_Aux[31:0]), .DIPA(0'b0), .DOA(DOA_Aux[31:0]), + .CLKB(~clk), .ENB(en_ev), .SSRB(1'b0), .ADDRB(evalfit_addr), .WEB(we_eval), .DIB(ev_do[31:0]), .DIPB(0'b0), .DOB(ev_di[31:0])); + +RAMB16_S36_S36 mem1( .CLKA(~clk), .ENA(en1), .SSRA(1'b0), .ADDRA(buffer_addr[11:3]), .WEA(we1), .DIA(DIA_Aux[31:0]), .DIPA(0'b0), .DOA(DOA_Aux[63:32]), + .CLKB(~clk), .ENB(en_ev),.SSRB(1'b0), .ADDRB(evalfit_addr), .WEB(we_eval), .DIB(ev_do[63:32]), .DIPB(0'b0), .DOB(ev_di[63:32])); + +// evalfit_peripheral +evalfit_peripheral evalfit( .clk(clk), .reset(~reset), .habilita(control[0]), .maxcombs(max_com), .nivel_max(max_lev), + .peripheral_mem_in(ev_di), .peripheral_mem_en(en_eval), .peripheral_mem_out(ev_do), .peripheral_mem_we(we_eval), + .peripheral_mem_addr(evalfit_addr), .evalfit3_estado(status), .errores(error), + .fin_ack(irq_pin), .reg0_s(reg0), .reg1_s(reg1), .reg2_s(reg2), .reg3_s(reg3), .reg4_s(reg4)); + +// MersenneTwister + mt_mem random( .clk(clk), .ena(1'b1), .resetn(reset), .random(mt_rnd)); + +endmodule + diff --git a/Examples/ehw4/logic/evalfit_peripheral.vhd b/Examples/ehw4/logic/evalfit_peripheral.vhd new file mode 100644 index 0000000..21f3225 --- /dev/null +++ b/Examples/ehw4/logic/evalfit_peripheral.vhd @@ -0,0 +1,482 @@ +-- 07/11/08 +-- Evalfit_peripheral +-- Evalua un arbol de 5 pentarboles, por ahora es valido hasta para *** 14 variables *** +-- Funciona hasta con 14 vars. +-- mapa: + -- 0 - 0x3F Cromosoma + -- 0x40 - 0x13F Objetivo. 16384 bits. Se empieza por el bit 0 MSB. + + +-- Cromosoma en memoria + -- bit bit Contenido + -- 28 a 31 Nivel del arbol + -- 32 a 47 LUT o tabla del arbol + -- 48 a 63 Variables de entrada del arbol (4 bits por variable) + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_ARITH.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL;---- Uncomment the following library declaration if instantiating +---- any Xilinx primitives in this code. +library UNISIM; +use UNISIM.VComponents.all; + +entity evalfit_peripheral is + Port ( clk, reset, habilita: in STD_LOGIC; + maxcombs : in STD_LOGIC_VECTOR (0 to 15); + nivel_max : in STD_LOGIC_VECTOR (0 to 3); + peripheral_mem_in : in STD_LOGIC_VECTOR (0 to 63); + peripheral_mem_en : out std_logic; + peripheral_mem_out : out STD_LOGIC_VECTOR (0 to 63); + peripheral_mem_we : out STD_LOGIC; + peripheral_mem_addr : out STD_LOGIC_VECTOR (0 to 8); + evalfit3_estado : out std_logic_vector(0 to 7); + errores : out STD_LOGIC_VECTOR (0 to 15); + fin_ack : out std_logic; + reg0_s : out STD_LOGIC_VECTOR (0 to 31); + reg1_s : out STD_LOGIC_VECTOR (0 to 31); + reg2_s : out STD_LOGIC_VECTOR (0 to 31); + reg3_s : out STD_LOGIC_VECTOR (0 to 31); + reg4_s : out STD_LOGIC_VECTOR (0 to 31) + ); +end evalfit_peripheral; + +architecture Behavioral of evalfit_peripheral is + +function mux16(sel: in std_logic_vector(0 to 3); ent: in std_logic_vector(0 to 15)) return std_logic is +begin + case sel is + when "0000" => return ent(15); + when "0001" => return ent(14); + when "0010" => return ent(13); + when "0011" => return ent(12); + when "0100" => return ent(11); + when "0101" => return ent(10); + when "0110" => return ent(9); + when "0111" => return ent(8); + when "1000" => return ent(7); + when "1001" => return ent(6); + when "1010" => return ent(5); + when "1011" => return ent(4); + when "1100" => return ent(3); + when "1101" => return ent(2); + when "1110" => return ent(1); + when others => return ent(0); + end case; +end mux16; + +function mux4(sel: in std_logic_vector(0 to 1); ent: in std_logic_vector(0 to 3)) return std_logic is +begin + case sel is + when "00" => return ent(3); + when "01" => return ent(2); + when "10" => return ent(1); + when others => return ent(0); + end case; +end mux4; + +-- senales para evaluar funciones +signal reg0, reg1, reg2, reg3, reg4, regn3, regn4:STD_LOGIC_VECTOR (0 to 31); +signal reg0_sig, reg1_sig, reg2_sig, reg3_sig, reg4_sig, regn3_sig, regn4_sig :STD_LOGIC_VECTOR (0 to 31); +signal sel_aux0, sel_aux1, sel_aux2, sel_aux3, sel_aux4, sel_auxn3, sel_auxn4, sal_arbol, minter_n3, minter_n4 : std_logic_vector(0 to 3); +signal salida_s, fin_ack_sig, fifow_wrreq_sig: std_logic; +signal entrada, errores_aux, errores_sig, salida_nivel : STD_LOGIC_VECTOR (0 to 15); + +-- senales para las memorias, guardan resultados de arboles intermedios +signal DO_n2, DI_n2, DO_n3, DI_n3, DO_n4, DI_n4: std_logic_vector(3 downto 0); +signal ADDR_n2, ADDR_n3, ADDR_n4: std_logic_vector(0 to 13); +signal WE_n2, WE_n3, WE_n4: std_logic_vector(3 downto 0); +signal WE_n2_sig, WE_n3_sig, WE_n4_sig: std_logic_vector(3 downto 0); +signal EN_n2, SSR, EN_n3, EN_n4: std_logic; + +-- senales para el control +type estado is (reset1, reset2, inicio, proceso, n1, n2, n3, n4, precuenta, cuenta, final, final2); +signal ep, es: estado; +signal nivel, nivel_sig, nivel_reg: std_logic_vector(0 to 3); +signal c1, c1_sig, c2, c2_sig, c3, c3_sig, c4, c4_sig: std_logic_vector(0 to 1); +signal conta, conta_sig, conta2, conta2_sig: std_logic_vector(0 to 15); +signal estado_evalf3, estado_evalf3_sig: std_logic_vector(0 to 7); +signal peripheral_mem_addr_aux, peripheral_mem_addr_sig, peripheral_mem_addr_crom_sig,peripheral_mem_addr_crom : STD_LOGIC_VECTOR (0 to 8); + +begin + + +process(ep, habilita, reg0, reg1, reg2, reg3, reg4, regn3, regn4, nivel, c1, c2, c3, c4, conta, + salida_s, salida_nivel, WE_n2, WE_n3, WE_n4, nivel_max, + maxcombs, peripheral_mem_in, peripheral_mem_addr_crom, peripheral_mem_addr_aux) +begin +es <= reset1; +WE_n2_sig <= "0000"; +WE_n3_sig <= "0000"; +WE_n4_sig <= "0000"; +reg0_sig <= reg0; +reg1_sig <= reg1; +reg2_sig <= reg2; +reg3_sig <= reg3; +reg4_sig <= reg4; +regn3_sig <= regn3; +regn4_sig <= regn4; +conta_sig <= conta; +conta2_sig <= conta2; +c1_sig <= c1; +c2_sig <= c2; +c3_sig <= c3; +c4_sig <= c4; +DI_n2 <= "0000"; +DI_n3 <= "0000"; +DI_n4 <= "0000"; +fin_ack_sig <= '0'; +peripheral_mem_addr_sig <= peripheral_mem_addr_aux; +peripheral_mem_addr_crom_sig <= peripheral_mem_addr_crom; +peripheral_mem_we <= '0'; +peripheral_mem_en <= '0'; +errores_sig <= errores_aux; +nivel_sig <= nivel_reg; +estado_evalf3_sig <= x"FF"; +case ep is + when reset1 => --poner la memoria a 0000 + WE_n2_sig <= "1111"; + WE_n3_sig <= "1111"; + WE_n4_sig <= "1111"; + conta2_sig <= (others => '0'); + es <= reset2; + when reset2 => + DI_n2 <= "0000"; + DI_n3 <= "0000"; + DI_n4 <= "0000"; + if(conta2 = maxcombs)then + WE_n2_sig <= "0000"; + WE_n3_sig <= "0000"; + WE_n4_sig <= "0000"; + conta2_sig <= (others => '0'); + es <= inicio; + else + WE_n2_sig <= "1111"; + WE_n3_sig <= "1111"; + WE_n4_sig <= "1111"; + conta2_sig <= conta2 + 1; + es <= reset2; + end if; + + when inicio => + if(habilita = '0') then + es <= inicio; + conta_sig <= (others => '0'); + conta2_sig <= (others => '0'); + peripheral_mem_addr_sig <= (others => '0'); + c1_sig <= "00"; + c2_sig <= "00"; + c3_sig <= "00"; + c4_sig <= "00"; + errores_sig <= x"0000"; + else + es <= proceso; + peripheral_mem_en <= '1'; + end if; + estado_evalf3_sig <= x"01"; + + when proceso => + peripheral_mem_en <= '1'; + if(nivel = "0001")then + case c1 is + when "00" => reg0_sig <= peripheral_mem_in(32 to 63); + when "01" => reg1_sig <= peripheral_mem_in(32 to 63); + when "10" => reg2_sig <= peripheral_mem_in(32 to 63); + when others => reg3_sig <= peripheral_mem_in(32 to 63); + end case; + es <= n1; + elsif(nivel = "0010")then + reg4_sig <= peripheral_mem_in(32 to 63); + WE_n2_sig(conv_integer(c2)) <= '1'; + DI_n2(conv_integer(c2)) <= salida_nivel(2); + es <= n2; + elsif(nivel = "0011")then + regn3_sig <= peripheral_mem_in(32 to 63); + WE_n3_sig(conv_integer(c3)) <= '1'; + DI_n3(conv_integer(c3)) <= salida_nivel(3); + es <= n3; + elsif(nivel = "0100")then + regn4_sig <= peripheral_mem_in(32 to 63); + WE_n4_sig(conv_integer(c4)) <= '1'; + DI_n4(conv_integer(c4)) <= salida_nivel(4); + es <= n4; + elsif(nivel = "1111")then + es <= final2; + end if; + peripheral_mem_addr_sig <= peripheral_mem_addr_aux + 1; + peripheral_mem_addr_crom_sig <= peripheral_mem_addr_aux + 1; + nivel_sig <= nivel; + estado_evalf3_sig <= x"02"; + + when n1 => + peripheral_mem_en <= '1'; + c1_sig <= c1 + 1; + peripheral_mem_addr_sig <= peripheral_mem_addr_aux; + es <= proceso; + estado_evalf3_sig <= x"03"; + + when n2 => + WE_n2_sig(conv_integer(c2)) <= '1'; + DI_n2(conv_integer(c2)) <= salida_nivel(2); + peripheral_mem_en <= '1'; + peripheral_mem_addr_sig <= "001000000" + ('0' & conta(2 to 9));-- esto es para que evalue el pentarbol y guarde en memoria la salida + es <= precuenta; + conta2_sig <= (others => '0'); + estado_evalf3_sig <= x"04"; + + when n3 => + WE_n3_sig(conv_integer(c3)) <= '1'; + DI_n3(conv_integer(c3)) <= salida_nivel(3); + peripheral_mem_en <= '1'; + peripheral_mem_addr_sig <= "001000000" + ('0' & conta(2 to 9));-- + es <= precuenta; + conta2_sig <= (others => '0'); + estado_evalf3_sig <= x"05"; + + when n4 => + WE_n4_sig(conv_integer(c4)) <= '1'; + DI_n4(conv_integer(c4)) <= salida_nivel(4); + peripheral_mem_en <= '1'; + peripheral_mem_addr_sig <= "001000000" + ('0' & conta(2 to 9));-- + es <= precuenta; + conta2_sig <= (others => '0'); + estado_evalf3_sig <= x"06"; + + when precuenta => + WE_n2_sig <= WE_n2; + WE_n3_sig <= WE_n3; + WE_n4_sig <= WE_n4; + DI_n2(conv_integer(c2)) <= salida_nivel(2); + DI_n3(conv_integer(c3)) <= salida_nivel(3); + DI_n4(conv_integer(c4)) <= salida_nivel(4); + peripheral_mem_en <= '1'; + peripheral_mem_addr_sig <= "001000000" + ('0' & conta2(2 to 9)); + conta_sig <= conta; + conta2_sig <= conta + 1; + es <= cuenta; + estado_evalf3_sig <= x"07"; + + when cuenta => + DI_n2(conv_integer(c2)) <= salida_nivel(2); + DI_n3(conv_integer(c3)) <= salida_nivel(3); + DI_n4(conv_integer(c4)) <= salida_nivel(4); + peripheral_mem_en <= '1'; + if(conta = maxcombs)then + WE_n2_sig <= "0000"; + WE_n3_sig <= "0000"; + WE_n4_sig <= "0000"; + conta_sig <= (others => '0'); + conta2_sig <= (others => '0'); + peripheral_mem_addr_sig <= peripheral_mem_addr_crom; --direccion de mem donde esta el cromosoma + es <= final; + else + WE_n2_sig <= WE_n2; + WE_n3_sig <= WE_n3; + WE_n4_sig <= WE_n4; + conta_sig <= conta + 1; + conta2_sig <= conta2 + 1; + peripheral_mem_addr_sig <= "001000000" + ('0' & conta2(2 to 9));--crear señal conta futura + if(conta(10 to 15) = "111111")then + es <= precuenta; + else + es <= cuenta; + end if; + end if; + if(nivel_reg = nivel_max)then + if(salida_nivel(conv_integer(nivel_max)) = peripheral_mem_in(conv_integer(conta(10 to 15))))then + errores_sig <= errores_aux; + else + errores_sig <= errores_aux + 1; + end if; + else + errores_sig <= errores_aux; + end if; + + estado_evalf3_sig <= x"08"; + + when final => + if(nivel_reg = "0010")then + c2_sig <= c2 + 1; + elsif(nivel_reg = "0011")then + c3_sig <= c3 + 1; + elsif(nivel_reg = "0100")then + c4_sig <= c4 + 1; + end if; + peripheral_mem_en <= '1'; + peripheral_mem_addr_sig <= peripheral_mem_addr_crom; + es <= proceso; + estado_evalf3_sig <= x"09"; + + when final2 => + if(habilita = '1') then + es <= final2; + else + es <= inicio; + end if; + fin_ack_sig <= '1'; + estado_evalf3_sig <= x"0A"; + when others => es <= inicio; + + end case; +end process; + + +process(clk, reset) +begin + if(reset = '1')then + ep <= reset1; + c1 <= "00"; + c2 <= "00"; + c3 <= "00"; + c4 <= "00"; + WE_n2 <= "0000"; + WE_n3 <= "0000"; + WE_n4 <= "0000"; + reg0 <= x"00000000"; + reg1 <= x"00000000"; + reg2 <= x"00000000"; + reg3 <= x"00000000"; + reg4 <= x"00000000"; + regn3 <= x"00000000"; + regn4 <= x"00000000"; + conta <= (others => '0'); + conta2 <= (others => '0'); + fin_ack <= '0'; + peripheral_mem_addr_aux <= "000000000"; + peripheral_mem_addr_crom <= "000000000"; + errores_aux <= (others => '0'); + nivel_reg <= "0000"; + estado_evalf3 <= x"00"; + elsif(rising_edge(clk))then + ep <= es; + c1 <= c1_sig; + c2 <= c2_sig; + c3 <= c3_sig; + c4 <= c4_sig; + WE_n2 <= WE_n2_sig; + WE_n3 <= WE_n3_sig; + WE_n4 <= WE_n4_sig; + reg0 <= reg0_sig; + reg1 <= reg1_sig; + reg2 <= reg2_sig; + reg3 <= reg3_sig; + reg4 <= reg4_sig; + regn3 <= regn3_sig; + regn4 <= regn4_sig; + conta <= conta_sig; + conta2 <= conta2_sig; + fin_ack <= fin_ack_sig; + peripheral_mem_addr_aux <= peripheral_mem_addr_sig; + peripheral_mem_addr_crom <= peripheral_mem_addr_crom_sig; + errores_aux <= errores_sig; + nivel_reg <= nivel_sig; + estado_evalf3 <= estado_evalf3_sig; + end if; +end process; + +process(nivel_reg, conta, conta2) +begin +case nivel_reg is + when "0000" => + ADDR_n2 <= conta(2 to 15); + ADDR_n3 <= conta(2 to 15); + ADDR_n4 <= conta(2 to 15); + when "0010" => + ADDR_n2 <= conta(2 to 15); + ADDR_n3 <= conta(2 to 15); + ADDR_n4 <= conta(2 to 15); + when "0011" => + ADDR_n2 <= conta2(2 to 15); + ADDR_n3 <= conta(2 to 15); + ADDR_n4 <= conta(2 to 15); + when "0100" => + ADDR_n2 <= conta(2 to 15); + ADDR_n3 <= conta2(2 to 15); + ADDR_n4 <= conta(2 to 15); + when others => + ADDR_n2 <= conta2(2 to 15); + ADDR_n3 <= conta2(2 to 15); + ADDR_n4 <= conta2(2 to 15); +end case; + +end process; + + +errores <= errores_aux; +peripheral_mem_addr <= peripheral_mem_addr_aux; +nivel <= peripheral_mem_in(28 to 31); +EN_n2 <= '1'; +EN_n3 <= '1'; +EN_n4 <= '1'; +SSR <= '0'; +minter_n3 <= DO_n2; +minter_n4 <= DO_n3; +entrada <= conta; + +evalfit3_estado <= estado_evalf3; +reg0_s <= reg0; +reg1_s <= reg1; +reg2_s <= reg2; +reg3_s <= reg3; +reg4_s <= reg4; +salida_nivel(1) <= sal_arbol(3); + +sel_aux0(3) <= mux16(reg0(28 to 31), entrada); +sel_aux0(2) <= mux16(reg0(24 to 27), entrada); +sel_aux0(1) <= mux16(reg0(20 to 23), entrada); +sel_aux0(0) <= mux16(reg0(16 to 19), entrada); +sal_arbol(3) <= mux16(sel_aux0, reg0(0 to 15)); -- reg0(0 to 15) = dato_lut + +sel_aux1(3) <= mux16(reg1(28 to 31), entrada); +sel_aux1(2) <= mux16(reg1(24 to 27), entrada); +sel_aux1(1) <= mux16(reg1(20 to 23), entrada); +sel_aux1(0) <= mux16(reg1(16 to 19), entrada); +sal_arbol(2) <= mux16(sel_aux1, reg1(0 to 15)); + +sel_aux2(3) <= mux16(reg2(28 to 31), entrada); +sel_aux2(2) <= mux16(reg2(24 to 27), entrada); +sel_aux2(1) <= mux16(reg2(20 to 23), entrada); +sel_aux2(0) <= mux16(reg2(16 to 19), entrada); +sal_arbol(1) <= mux16(sel_aux2, reg2(0 to 15)); + +sel_aux3(3) <= mux16(reg3(28 to 31), entrada); +sel_aux3(2) <= mux16(reg3(24 to 27), entrada); +sel_aux3(1) <= mux16(reg3(20 to 23), entrada); +sel_aux3(0) <= mux16(reg3(16 to 19), entrada); +sal_arbol(0) <= mux16(sel_aux3, reg3(0 to 15)); + +sel_aux4(3) <= mux4(reg4(30 to 31), sal_arbol); --arbol de 2do nivel +sel_aux4(2) <= mux4(reg4(26 to 27), sal_arbol); +sel_aux4(1) <= mux4(reg4(22 to 23), sal_arbol); +sel_aux4(0) <= mux4(reg4(18 to 19), sal_arbol); +salida_nivel(2) <= mux16(sel_aux4, reg4(0 to 15)); + +sel_auxn3(3) <= mux4(regn3(30 to 31), minter_n3); --arboles de 3er nivel +sel_auxn3(2) <= mux4(regn3(26 to 27), minter_n3); +sel_auxn3(1) <= mux4(regn3(22 to 23), minter_n3); +sel_auxn3(0) <= mux4(regn3(18 to 19), minter_n3); +salida_nivel(3) <= mux16(sel_auxn3, regn3(0 to 15)); + +sel_auxn4(3) <= mux4(regn4(30 to 31), minter_n4); --arboles de 4to nivel +sel_auxn4(2) <= mux4(regn4(26 to 27), minter_n4); +sel_auxn4(1) <= mux4(regn4(22 to 23), minter_n4); +sel_auxn4(0) <= mux4(regn4(18 to 19), minter_n4); +salida_nivel(4) <= mux16(sel_auxn4, regn4(0 to 15)); + +ram_nivel20:RAMB16_S1 port map(DO => DO_n2(3 downto 3), ADDR => ADDR_n2, CLK => clk, DI => DI_n2(3 downto 3), EN => EN_n2, SSR => SSR, WE => WE_n2(3)); +ram_nivel21:RAMB16_S1 port map(DO => DO_n2(2 downto 2), ADDR => ADDR_n2, CLK => clk, DI => DI_n2(2 downto 2), EN => EN_n2, SSR => SSR, WE => WE_n2(2)); +ram_nivel22:RAMB16_S1 port map(DO => DO_n2(1 downto 1), ADDR => ADDR_n2, CLK => clk, DI => DI_n2(1 downto 1), EN => EN_n2, SSR => SSR, WE => WE_n2(1)); +ram_nivel23:RAMB16_S1 port map(DO => DO_n2(0 downto 0), ADDR => ADDR_n2, CLK => clk, DI => DI_n2(0 downto 0), EN => EN_n2, SSR => SSR, WE => WE_n2(0)); + +ram_nivel30:RAMB16_S1 port map(DO => DO_n3(3 downto 3), ADDR => ADDR_n3, CLK => clk, DI => DI_n3(3 downto 3), EN => EN_n3, SSR => SSR, WE => WE_n3(3)); +ram_nivel31:RAMB16_S1 port map(DO => DO_n3(2 downto 2), ADDR => ADDR_n3, CLK => clk, DI => DI_n3(2 downto 2), EN => EN_n3, SSR => SSR, WE => WE_n3(2)); +ram_nivel32:RAMB16_S1 port map(DO => DO_n3(1 downto 1), ADDR => ADDR_n3, CLK => clk, DI => DI_n3(1 downto 1), EN => EN_n3, SSR => SSR, WE => WE_n3(1)); +ram_nivel33:RAMB16_S1 port map(DO => DO_n3(0 downto 0), ADDR => ADDR_n3, CLK => clk, DI => DI_n3(0 downto 0), EN => EN_n3, SSR => SSR, WE => WE_n3(0)); + +ram_nivel40:RAMB16_S1 port map(DO => DO_n4(3 downto 3), ADDR => ADDR_n4, CLK => clk, DI => DI_n4(3 downto 3), EN => EN_n4, SSR => SSR, WE => WE_n4(3)); +ram_nivel41:RAMB16_S1 port map(DO => DO_n4(2 downto 2), ADDR => ADDR_n4, CLK => clk, DI => DI_n4(2 downto 2), EN => EN_n4, SSR => SSR, WE => WE_n4(2)); +ram_nivel42:RAMB16_S1 port map(DO => DO_n4(1 downto 1), ADDR => ADDR_n4, CLK => clk, DI => DI_n4(1 downto 1), EN => EN_n4, SSR => SSR, WE => WE_n4(1)); +ram_nivel43:RAMB16_S1 port map(DO => DO_n4(0 downto 0), ADDR => ADDR_n4, CLK => clk, DI => DI_n4(0 downto 0), EN => EN_n4, SSR => SSR, WE => WE_n4(0)); + +end Behavioral; + diff --git a/Examples/ehw4/logic/mt.vhd b/Examples/ehw4/logic/mt.vhd new file mode 100755 index 0000000..4d8f8f6 --- /dev/null +++ b/Examples/ehw4/logic/mt.vhd @@ -0,0 +1,191 @@ +------------------------------------------------------------------------------- +-- -- +-- MT32 - Mersenne Twister -- +-- Copyright (C) 2007 HT-LAB -- +-- -- +-- Contact : Use feedback form on the website. -- +-- Web: http://www.ht-lab.com -- +-- -- +-- MT32 files are released under the GNU General Public License. -- +-- -- +------------------------------------------------------------------------------- +-- -- +-- This library is free software; you can redistribute it and/or -- +-- modify it under the terms of the GNU Lesser General Public -- +-- License as published by the Free Software Foundation; either -- +-- version 2.1 of the License, or (at your option) any later version. -- +-- -- +-- This library is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- +-- Lesser General Public License for more details. -- +-- -- +-- Full details of the license can be found in the file "copying.txt". -- +-- -- +-- You should have received a copy of the GNU Lesser General Public -- +-- License along with this library; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------- +-- -- +-- Top Level (Synthesis) -- +------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.all; +USE ieee.std_logic_unsigned.all; +USE ieee.std_logic_arith.all; + +ENTITY mt_mem IS + PORT( + clk : IN std_logic; + ena : IN std_logic; + resetn : IN std_logic; + random : OUT std_logic_vector (31 DOWNTO 0) + ); + +END mt_mem ; + +LIBRARY ieee; + +ARCHITECTURE struct OF mt_mem IS + + -- Architecture declarations + + -- internal signal declarations + signal kk_cnt : std_logic_vector(9 downto 0); + signal km_cnt : std_logic_vector(9 downto 0); + signal kp_cnt : std_logic_vector(9 downto 0); + signal mt_kk31 : std_logic_vector(0 downto 0); + signal mt_kk_s : std_logic_vector(31 downto 0); + signal mt_km : std_logic_vector(31 downto 0); + signal mt_kp : std_logic_vector(30 downto 0); + signal wea : std_logic; + signal wea_s : std_logic_vector(0 downto 0); + signal wr_cnt : std_logic_vector(9 downto 0); + + + signal xor1_s : std_logic_vector(31 downto 0); + signal xor2_s : std_logic_vector(31 downto 0); + signal xor3_s : std_logic_vector(31 downto 0); + signal y_s : std_logic_vector(31 downto 0); + signal mag01_s : std_logic_vector(31 downto 0); + + -- Component Declarations + COMPONENT counters + GENERIC ( + M : integer := 397; + N : integer := 623 + ); + PORT ( + clk : IN std_logic ; + resetn : IN std_logic ; + ena : IN std_logic ; + wea : OUT std_logic ; + kk_cnt : OUT std_logic_vector (9 DOWNTO 0); + km_cnt : OUT std_logic_vector (9 DOWNTO 0); + kp_cnt : OUT std_logic_vector (9 DOWNTO 0); + wr_cnt : OUT std_logic_vector (9 DOWNTO 0) + ); + END COMPONENT; + COMPONENT dpram624x1 + PORT ( + addra : IN std_logic_VECTOR (9 DOWNTO 0); + addrb : IN std_logic_VECTOR (9 DOWNTO 0); + clka : IN std_logic; + clkb : IN std_logic; + dina : IN std_logic_VECTOR (0 DOWNTO 0); + wea : IN std_logic_VECTOR (0 DOWNTO 0); + doutb : OUT std_logic_VECTOR (0 DOWNTO 0) + ); + END COMPONENT; + COMPONENT dpram624x31 + PORT ( + addra : IN std_logic_VECTOR (9 DOWNTO 0); + addrb : IN std_logic_VECTOR (9 DOWNTO 0); + clka : IN std_logic; + clkb : IN std_logic; + dina : IN std_logic_VECTOR (30 DOWNTO 0); + wea : IN std_logic_VECTOR (0 DOWNTO 0); + doutb : OUT std_logic_VECTOR (30 DOWNTO 0) + ); + END COMPONENT; + COMPONENT dpram624x32 + PORT ( + addra : IN std_logic_VECTOR (9 DOWNTO 0); + addrb : IN std_logic_VECTOR (9 DOWNTO 0); + clka : IN std_logic; + clkb : IN std_logic; + dina : IN std_logic_VECTOR (31 DOWNTO 0); + wea : IN std_logic_VECTOR (0 DOWNTO 0); + doutb : OUT std_logic_VECTOR (31 DOWNTO 0) + ); + END COMPONENT; + + +BEGIN + -- Architecture concurrent statements + -- HDL Embedded Text Block 1 eb1 + -- eb1 1 + wea_s(0) <= wea; -- wonderful VHDL + + -- HDL Embedded Text Block 2 XOR_CHAIN1 + -- eb1 1 + xor1_s <= mt_kk_s XOR ("00000000000"&mt_kk_s(31 downto 11)); + xor2_s <= xor1_s XOR (xor1_s(24 downto 0)&"0000000" AND X"9D2C5680"); + xor3_s <= xor2_s XOR (xor2_s(16 downto 0)&"000000000000000" AND X"EFC60000"); + random <= xor3_s XOR "000000000000000000"&xor3_s(31 downto 18); + + -- HDL Embedded Text Block 3 eb3 + y_s <= mt_kk31(0)&mt_kp(30 downto 0); + mag01_s <= X"00000000" when y_s(0)='0' else X"9908B0DF"; + mt_kk_s <= mt_km XOR ('0'&y_s(31 downto 1)) XOR mag01_s; + + + -- Instance port mappings. + U_7 : counters + GENERIC MAP ( + M => 397, + N => 623 + ) + PORT MAP ( + clk => clk, + resetn => resetn, + ena => ena, + wea => wea, + kk_cnt => kk_cnt, + km_cnt => km_cnt, + kp_cnt => kp_cnt, + wr_cnt => wr_cnt + ); + U_0 : dpram624x1 + PORT MAP ( + clka => clk, + dina => mt_kk_s(31 DOWNTO 31), + addra => wr_cnt, + wea => wea_s, + clkb => clk, + addrb => kk_cnt, + doutb => mt_kk31 + ); + U_1 : dpram624x31 + PORT MAP ( + clka => clk, + dina => mt_kk_s(30 DOWNTO 0), + addra => wr_cnt, + wea => wea_s, + clkb => clk, + addrb => kp_cnt, + doutb => mt_kp + ); + U_2 : dpram624x32 + PORT MAP ( + clka => clk, + dina => mt_kk_s, + addra => wr_cnt, + wea => wea_s, + clkb => clk, + addrb => km_cnt, + doutb => mt_km + ); + +END struct; diff --git a/Examples/ehw4/logic/reg_bank.v b/Examples/ehw4/logic/reg_bank.v new file mode 100644 index 0000000..b51c7fc --- /dev/null +++ b/Examples/ehw4/logic/reg_bank.v @@ -0,0 +1,96 @@ +`timescale 1ns / 1ps + +module reg_bank(clk, reset, en, we, wdBus, rdBus, address, reg0, reg1, reg2, reg3, reg4, regMT, error, status, max_lev, max_com, control); + + input clk, reset, en, we; + + input [7:0] wdBus; + output [7:0] rdBus; + input [4:0] address; + + input [31:0] reg0; + input [31:0] reg1; + input [31:0] reg2; + input [31:0] reg3; + input [31:0] reg4; + input [31:0] regMT; + input [16:0] error; + input [7:0] status; + output [15:0] max_com; + output [7:0] max_lev; + output [7:0] control; + + + reg [7:0] reg_bank [31:0]; + reg [7:0] rdBus; + + + + // Read control + always @(posedge clk) + if(reset) + rdBus = 8'h00; + else begin + rdBus = reg_bank[address]; + end + + + // Store Inputs + always @(posedge clk) + begin + if(en) begin + reg_bank[0] = reg0[7:0]; + reg_bank[1] = reg0[15:8]; + reg_bank[2] = reg0[23:16]; + reg_bank[3] = reg0[31:24]; + + reg_bank[4] = reg1[7:0]; + reg_bank[5] = reg1[15:8]; + reg_bank[6] = reg1[23:16]; + reg_bank[7] = reg1[31:24]; + + reg_bank[8] = reg2[7:0]; + reg_bank[9] = reg2[15:8]; + reg_bank[10] = reg2[23:16]; + reg_bank[11] = reg2[31:24]; + + reg_bank[12] = reg3[7:0]; + reg_bank[13] = reg3[15:8]; + reg_bank[14] = reg3[23:16]; + reg_bank[15] = reg3[31:24]; + + reg_bank[16] = reg4[7:0]; + reg_bank[17] = reg4[15:8]; + reg_bank[18] = reg4[23:16]; + reg_bank[19] = reg4[31:24]; + + reg_bank[20] = error[7:0]; + reg_bank[21] = error[15:8]; + + reg_bank[22] = { 4'b0, status}; + +// reg_bank[23] = regMT[7:0]; +// reg_bank[24] = regMT[15:8]; +// reg_bank[25] = regMT[23:16]; +// reg_bank[26] = regMT[31:24]; + end + end + + + assign max_com[7:0] = reg_bank[26]; + assign max_com[15:8] = reg_bank[27]; + assign max_lev = reg_bank[28]; + assign control = reg_bank[29]; + + // Write control + always @(negedge clk) + if(we & en) begin + case (address) + 27: reg_bank[26] = wdBus; + 28: reg_bank[27] = wdBus; + 29: reg_bank[28] = wdBus; + 30: reg_bank[29] = wdBus; + endcase + end + +endmodule diff --git a/Examples/ehw4/src/Makefile b/Examples/ehw4/src/Makefile new file mode 100644 index 0000000..b8c4d33 --- /dev/null +++ b/Examples/ehw4/src/Makefile @@ -0,0 +1,33 @@ +CC = mipsel-openwrt-linux-gcc + +all: jz_init_sram jz_test_gpio enable_rx enable_irq + +DEBUG = -O3 -g0 + +COMMON_SOURCES = jz47xx_gpio.c jz47xx_mmap.c + +H_SOURCES = jz47xx_gpio.h jz47xx_mmap.h + +INCLUDE = -I. + +WARNINGS= -Wcast-align -Wpacked -Wpadded -Wall + +CCFLAGS = ${INCLUDE} ${DEBUG} ${WARNINGS} + +LDFLAGS = + +COMMON_OBJECTS = $(COMMON_SOURCES:.c=.o) + +NANO_IP = 192.168.254.101 + +genetic.o: genetic.c genetic.h + ${CC} -lm -I. -c genetic.c -o genetic.o + +client: sintesishw_client.c genetic.o sintesishw_client.h + ${CC} sintesishw_client.c genetic.o -o sintesishw_client -lm -I. + +server: sintesishw_server.c genetic.o + ${CC} sintesishw_server.c genetic.o -o sintesishw_server -lm -lpthread -I. + +clean: + rm -f *.o sintesishw_client sintesishw_server ${EXEC} *~ diff --git a/Examples/ehw4/src/funlut.dat b/Examples/ehw4/src/funlut.dat new file mode 100644 index 0000000000000000000000000000000000000000..4c8a5fa093f203255b3e56d370abd505333a716c GIT binary patch literal 250 zcmX}nAr6Kh7=U4l&KcbP3veb1g(8W~WRysgW@EEaC={=R7tjP_1o)HRbAtEv{KZ*8^K>ni>#t&{?J MR09DX@ZEa<2bx`j>i_@% literal 0 HcmV?d00001 diff --git a/Examples/ehw4/src/genetic.c b/Examples/ehw4/src/genetic.c new file mode 100644 index 0000000..9d43add --- /dev/null +++ b/Examples/ehw4/src/genetic.c @@ -0,0 +1,816 @@ +#include "stdio.h" +#include "termios.h" +#include "sys/mman.h" +#include "stdlib.h" +#include "sys/types.h" +#include "sys/stat.h" +#include "fcntl.h" +#include "time.h" +#include "math.h" +#include "pthread.h" +#include "sys/socket.h" +#include "netinet/in.h" +#include "netdb.h" +#include "errno.h" +#include "sys/un.h" +#include "genetic.h" + +/************************************************************************************************************************************** + imprime un cromosoma completo */ +void mostrar_indiv(char *cromo, int pentarboles, int vars) +{ +char *ap, i, fn[8] = {'!', '&', '^', '|', '_'}; //NOT, AND, XOR, OR, NADA o YES +char vn[] = {'A', 'B', 'C', 'D', 'E' , 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', '.'}; +char f1,f2,f3; +char a; + +ap = cromo; + +for(i = 0; i < ARBOLES_INDIV; i++){ + if(*(cromo + 7) == 1) + { + vn[vars] = '.'; + printf("%0x%c%c%c%c %i ", *(unsigned short int *)ap, vn[(*(ap+2) >> 4) & 0xF], vn[*(ap+2) & 0xF], vn[(*(ap+3) >> 4) & 0xF], vn[*(ap+3) & 0xF], *(ap+6)); + } + else + { + vn[4] = '.'; + printf("%0x%c%c%c%c %i", *(unsigned short int *)ap, vn[(*(ap+2) >> 4) & 0xF], vn[*(ap+2) & 0xF], vn[(*(ap+3) >> 4) & 0xF], vn[*(ap+3) & 0xF], *(ap+6)); + } +// printf("\t %0x %0x ", *(short int *)(ap+2), *(ap+6) ); + ap = ap + LONG_ARBOL; +} + +printf(" "); +for(i = 0; i < LONG_INDIV; i++) +{ a=*(char *)(cromo+i) & 0xff; + printf("%hhu,",a); +} +//fflush(stdout); +} + +/************************************************************************************************************************************** + imprime un arbol completo */ +mostrar_arbol(char *cromo, int vars) +{ + char *ap, i, fn[8] = {'!', '&', '^', '|', '_'}; //NOT, AND, XOR, OR, NADA o YES + char vn[] = {'A', 'B', 'C', 'D', 'E' , 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', '.'}; + ap = cromo; + + if(*(cromo + 7) == 1) + { + vn[vars] = '.'; + printf("LUT:%04x VARS:%c%c%c%c %0x", *(unsigned short int *)ap, vn[*(ap+2) >> 4], vn[*(ap+2) & 0xF], vn[*(ap+3) >> 4], vn[*(ap+3) & 0xF], *(ap+6)); + } + else + { + vn[4] = '.'; + printf("LUT:%04x VARS:%c%c%c%c %0x", *(unsigned short int *)ap, vn[*(ap+2) >> 4], vn[*(ap+2) & 0xF], vn[*(ap+3) >> 4], vn[*(ap+3) & 0xF], *(ap+6)); + } + printf("\tVARS:%04x \tLUT_index:%0x \t", *(unsigned short int *)(ap+2), *(ap+6) ); + for(i = 0; i < LONG_ARBOL; i++) + { + printf("%0x,",*(cromo+i)); + } + printf("\n"); +} + +/************************************************************************************************************************************** + genera un numero de forma aleatoria hasta max inclusive*/ +char random_var(int max) +{ + char variable, mascara; + int i; + mascara = 1; + do + { + mascara = (mascara << 1) + 1; + }while(max > mascara); + + if(HW_ENABLE == 1) variable = (*(int *)(evalfit_ptr1 + EVALFIT_RDREG8)) & mascara; + else variable = random() & mascara; + + while(variable > max) + { + variable = variable - max; + } + return variable; +} + +/************************************************************************************************************************************** + Genera un arbol de forma aleatoria + Las funciones y variables son representadas por enteros del 0 al 3 o mas... + - el arbol se encuentra compuesto de tres funciones, dos de entrada y una de salida. +*/ +void gen_arbol(char *ap, int variables) +{ + int lut; + short int dato_lut; + lut = (random_var(FUNCIONES)*25) + (random_var(FUNCIONES) * 5) + random_var(FUNCIONES);//random_var(FUNCOMBS-1); + dato_lut = (*(funlut_ap+(lut*2)) << 8) + (*(funlut_ap+(lut*2)+1)); + *(short int *)ap = ntohs(dato_lut); //Se cambia endianismo para cuando se ejecute en 386, que es distinto a PPC + *(ap+2) = *(ap+3) = 0; + *(ap+2) = random_var(variables) + (random_var(variables) << 4); + *(ap+3) = random_var(variables) + (random_var(variables) << 4); + *(ap+6) = lut; +// mostrar_arbol(ap); +} + + +/************************************************************************************************************************************** + genera un individuo de forma aleatoria */ +void gen_indiv(char *cromo, int pentarboles, int vars) +{ +char i=0; +int n1, n2, n3, n4, n5, c1, c2, c3, c4, c5, sig, indice; + +n1 = n2 = n3 = n4 = n5 = 0; +c1 = c2 = c3 = c4 = c5 = 0; +indice = 0; + +sig=1; + + +do +{ + +if((sig == 1) && (c1 < nivel1)) +{ + gen_arbol(cromo + (indice * LONG_ARBOL), vars-1); + *(cromo +(indice*LONG_ARBOL) + 7) = 1; + n1 ++; + c1 ++; + indice ++; + if(n1 < 4) + sig = 1; + else + { + sig = 2; + n1 = 0; + }//printf("1"); +} +else +{ + if((sig == 2) && (c2 < *(nivel2+pentarboles))) + { + gen_arbol(cromo + (indice*LONG_ARBOL), 3); + *(cromo +(indice*LONG_ARBOL) + 7) = 2; + n2++; + c2 ++; + indice ++; + if(c2 == *(nivel2+pentarboles)) + sig = 3; + else + { + if(n2 < 4) + sig = 1; + else + { + sig = 3; + n2 = 0; + } + }//printf("2"); + } + else + { + if((sig == 3) && (c3 < *(nivel3+pentarboles))) + { + gen_arbol(cromo + (indice*LONG_ARBOL), 3); + *(cromo +(indice*LONG_ARBOL) + 7) = 3; + n3++; + c3++; + indice++; + if(c3 == *(nivel3+pentarboles)) + sig = 4; + else + { + if(n3 < 4) + sig = 1; + else + { + sig = 4; + n3 = 0; + } + }//printf("3"); + } + else + { + if((sig == 4) && (c4 < *(nivel4+pentarboles))) + { + gen_arbol(cromo + (indice*LONG_ARBOL), 3); + *(cromo +(indice*LONG_ARBOL) + 7) = 4; + n4++; + c4++; + indice++; + if(c4 == *(nivel4+pentarboles)) + sig = 5; + else + { + if(n4 < 4) + sig = 1; + else + { + sig = 5; + n4 = 0; + } + }//printf("4"); + } + else + { + if((sig == 5) && (c5 < *(nivel5+pentarboles))) + { + gen_arbol(cromo + (indice*LONG_ARBOL), 3); + *(cromo +(indice*LONG_ARBOL) + 7) = 5; + c5++; + indice++; + if(c5 == *(nivel5+pentarboles)) + sig = 1; + else + sig = 1; + } + } + + } + } + +} +/* mostrar_indiv(cromo, 1,vars); //*/ +}while(indice < ARBOLES_INDIV); + +} + + +/************************************************************************************************************************************** + genera una poblacion completa */ +void gen_poblacion(char *cromo, int pentarboles, int vars, int indivs) +{ + int i; + for(i=0; i < indivs; i++) + { + gen_indiv(cromo + ( i * LONG_INDIV), pentarboles, vars); + } +} + + +/************************************************************************************************************************************** + halla la salida de un arbol para una entrada de x de un cromo basado en LUT*/ +int eval_func_lut(char *ap, int x, int vars ) //var apunta al valor de las variables +{ +char Y; +char var[vars], i, a, b, c, d; +int lut; + +for(i=0;i <= vars-1;i++) +{ + var[i] = (x >> i) & 0x1; +// printf("-%i",var[i]); +} +var[vars] = 0; + +a = *(ap + 3) & 0xF; +b = (*(ap + 3) >> 4) & 0xF; +c = *(ap + 2) & 0xF; +d = (*(ap + 2) >> 4) & 0xF; +i = var[a] + (var[b]*2) + (var[c]*4) + (var[d]*8); +lut = *(short int *)ap; +Y = (lut >> i) & 0x1; + +return Y; +} + +/************************************************************************************************************************************** + retorna las salidas de un cromosoma de 5 arboles*/ +void eval_pentarbol_sw(char *ap, int *salida, int *entrada, int vars) +{ + int i, k ; + char salidas[ARBOLES][COMBS], aux[COMBS]; + + for(i=0; i <= ARBOLES-2; i++){ //se evaluan las salidas de los primeros arboles y se almacenan en salidas + for(k=0; k<= (COMBS-1); k++) + { + salidas[i][k] = eval_func_lut((ap+(i*LONG_ARBOL)), k, vars); + } + } + + //se calculan los minterminos para el arbol de salida + for(k=0; k <= (COMBS-1); k++) + { + aux[k] = ((salidas[0][k])*1) + ((salidas[1][k])*2) + ((salidas[2][k])*4) + ((salidas[3][k])*8); + } + + for(i=0; i <= (COMBS-1); i++) + { + *(salida + i) = eval_func_lut(ap + ((ARBOLES-1) * LONG_ARBOL), aux[i], vars); + } +} + + +/************************************************************************************************************************************** + retorna el numero de errores y las salidas de un cromosoma de 1 o mas pentarboles*/ +int eval_fit_sw(char *ap, int *objetivo, int num_min, int pentarboles, int vars ) +{ + int *obj_min, *med_min2, *med_min3, *med_min4, *med_min5, *entrada, i, j, errores, puertas; + int *salida, n2, n3, n4, n5, x; + + obj_min = malloc(sizeof(obj_min)*COMBS); + med_min2 = malloc(sizeof(med_min2)*COMBS); + med_min3 = malloc(sizeof(med_min3)*COMBS); + med_min4 = malloc(sizeof(med_min4)*COMBS); + med_min5 = malloc(sizeof(med_min5)*COMBS); + entrada = malloc(sizeof(entrada)*COMBS); + salida = malloc(sizeof(salida)*COMBS); + errores = 0; + + for(i=0; i < COMBS; i++) + { + *(obj_min+i) = 0; + *(entrada+i) = i; + *(med_min2 + i) = 0; + *(med_min3 + i) = 0; + *(med_min4 + i) = 0; + *(med_min5 + i) = 0; + } + + for(i = 0; i < num_min; i++) + { + *(obj_min + (*(objetivo + i))) = 1; //se convierte el objetivo a un arreglo + } + + i = 0; + n2 = 0; + n3 = 0; + n4 = 0; + n5 = 0; + + do + { + if(*(ap + (i * LONG_ARBOL) + 7) == 1) + { + eval_pentarbol_sw(ap + (i * LONG_ARBOL), salida, entrada, vars); + for(j = 0; j < COMBS; j++) + { + *(med_min2 + j) = *(med_min2 + j) + (*(salida + j) << n2); + } + if(n2 == 3) n2 = 0; else n2++; + i = i + 5; + } + else + { + if(*(ap + (i * LONG_ARBOL) + 7) == 3) + { + for(j = 0; j < COMBS; j++) + { + *(salida + j) = eval_func_lut(ap + (i * LONG_ARBOL), *(med_min2 + j), vars); + } + for(j = 0; j < COMBS; j++) + { + *(med_min3 + j) = *(med_min3 + j) + (*(salida + j) << n3); + } + if(n3 == 3) n3 = 0; else n3++; + i++; + } + else + { + + if(*(ap + (i * LONG_ARBOL) + 7) == 4) + { + for(j = 0; j < COMBS; j++) + { + *(salida + j) = eval_func_lut(ap + (i * LONG_ARBOL), *(med_min3 + j), vars); + } + for(j = 0; j < COMBS; j++) + { + *(med_min4 + j) = *(med_min4 + j) + (*(salida + j) << n4); + } + if(n4 == 3) n4 = 0; else n4++; + i++; + } + } + } + }while(i <= (ARBOLES_INDIV-1)); + + if(*(ap + ((ARBOLES_INDIV-1) * LONG_ARBOL) + 7) == 2) + { + for(j = 0; j < COMBS; j++) //se evalua el arbol de salida + { + errores = errores + abs(*(med_min2 + j) - *(obj_min + j)); //errores +/* printf("[%i]",*(med_min2 + j));*/ + } + } + + if(*(ap + ((ARBOLES_INDIV-1) * LONG_ARBOL) + 7) == 3) + { + for(j = 0; j < COMBS; j++) //se evalua el arbol de salida + { + errores = errores + abs(*(med_min3 + j) - *(obj_min + j)); //errores + } + } + + if(*(ap + ((ARBOLES_INDIV-1) * LONG_ARBOL) + 7) == 4) + { + for(j = 0; j < COMBS; j++) //se evalua el arbol de salida + { + errores = errores + abs(*(med_min4 + j) - *(obj_min + j)); //errores + } + } + + if(*(ap + ((ARBOLES_INDIV-1) * LONG_ARBOL) + 7) == 5) + { + for(j = 0; j < COMBS; j++) //se evalua el arbol de salida + { + errores = errores + abs(*(med_min5 + j) - *(obj_min + j)); //errores + } + } + free(obj_min); + free(med_min2); + free(med_min3); + free(med_min4); + free(med_min5); + free(entrada); + free(salida); + + puertas = 0; + + return ((errores * PESO_SALIDA) + puertas); +} + +/************************************************************************************************************************************** + inicia la evaluacion de un cromosoma en un periferico*/ +int evalfit_hw_init(char *cromo, int pentarboles, int nivel_max, void *evalfit_ptr ) +{ +int i; + +/** insertar cromosoma en periferico **/ + for(i = 0; i < ARBOLES_INDIV; i++) + { + *(int *)((evalfit_ptr) + EVALFIT_MEMOFFSET + (LONG_ARBOL*i)) = *(char *)(cromo +(LONG_ARBOL*i)+7); +// printf("\n%i: %0x",i,*(int *)(evalfit_ptr + EVALFIT_MEMOFFSET + (LONG_ARBOL*i))); + *(int *)((evalfit_ptr) + EVALFIT_MEMOFFSET + (LONG_ARBOL*i) + 4) = *(int *)(cromo +(LONG_ARBOL*i)); +// printf(": %0x",*(int *)(evalfit_ptr + EVALFIT_MEMOFFSET + (LONG_ARBOL*i)+4)); + } + *(int *)((evalfit_ptr) + EVALFIT_MEMOFFSET + (LONG_ARBOL*i)) = 0xF; //para terminar + i++; + *(int *)((evalfit_ptr) + EVALFIT_MEMOFFSET + (LONG_ARBOL*i)) = 0xF; //para terminar + +/** Iniciar **/ + *(int *)(evalfit_ptr + EVALFIT_CONTROL_OFFSET) = CONTROL_START_MASK; +} + +/************************************************************************************************************************************** + espera y retorna el numero de errores y las salidas de un cromosoma de 1 o mas pentarboles*/ +int evalfit_hw_wait(char *cromo, int pentarboles, int nivel_max, void *evalfit_ptr ) +{ +int errores, puertas, i; + + // tiempo1 = get_timestamp(); + do{ }while((*(int *)(evalfit_ptr + EVALFIT_RDREG1) & DONE_MASK) != 1); + // tiempo2 = get_timestamp(); + errores = *(int *)(evalfit_ptr + EVALFIT_RDREG2) & ERRORS_MASK; //errores + *(int *)(evalfit_ptr + EVALFIT_CONTROL_OFFSET) = 0; //terminar, bajar habilita + + puertas = 0; + for(i = 0; i < ARBOLES_INDIV; i++) + { + puertas = puertas + *(puertas_ap + *(char *)(cromo +(LONG_ARBOL*i)+6)); + } + +return ((errores * PESO_SALIDA) + (PESO_PUERTAS * puertas) + (PESO_NIVELES * nivel_max)); +} + +/************************************************************************************************************************************** + cruza dos cromosomas y almacena en destino. */ +void cruzar(char *padre1, char *padre2, char *destino1, char *destino2, int pentarboles) +{ +int a, i; + + a = (random() & 0x1F) + 1; //punto de corte, es un numero de arbol + + while(a > (ARBOLES_INDIV)) + { + a = a - ARBOLES_INDIV;//(pentarboles * ARBOLES); + } + a = a-1; +// printf("\n%i",a); + + for(i = 0; i < (a * LONG_ARBOL); i++) + { + *(destino1 + i) = *(padre1 + i); //padre1 + *(destino2 + i) = *(padre2 + i); //padre1 + } + + for(i = (a * LONG_ARBOL); i < LONG_INDIV; i++) // +1 para el arbol de salida + { + *(destino1 + i) = *(padre2 + i); //padre2 + *(destino2 + i) = *(padre1 + i); //padre2 + } +} + +/************************************************************************************************************************************** + cruza dos cromosomas y almacena en destino. */ +void cross2point(char *padre1, char *padre2, char *destino1, char *destino2, int pentarboles) +{ +int a, b, i; + + a = random_var((pentarboles*ARBOLES)-3); + b = random_var((pentarboles*ARBOLES)-a-2)+a; + a++; + b++; +// printf("\n%i %i %i",a,b,pentarboles*ARBOLES);fflush(stdout); + for(i = 0; i < (a*LONG_ARBOL) ; i++) + { + *(destino1 + i) = *(padre1 + i); // + *(destino2 + i) = *(padre2 + i); // + } + for(i = a; i < (b*LONG_ARBOL) ; i++) + { + *(destino2 + i) = *(padre1 + i); // + *(destino1 + i) = *(padre2 + i); // + } + for(i = (b*LONG_ARBOL); i < LONG_INDIV; i++) // +1 para el arbol de salida + { + *(destino1 + i) = *(padre1 + i); //padre2 + *(destino2 + i) = *(padre2 + i); //padre2 + } +} + +/************************************************************************************************************************************** + muta un cromosoma y almacena en destino. */ + +void muta_indiv(char *padre, char *destino, int pentarboles, int vars) +{ + int a, i; + + gen_indiv(destino, pentarboles, vars); + + a = (random() & 0x1F) + 1; //punto de corte, es un numero de arbol + + while(a > (ARBOLES_INDIV)) + { + a = a - ARBOLES_INDIV; + } + + for(i = 0; i < (a * LONG_ARBOL); i++) + { + *(destino + i) = *(padre + i); //padre1 + } +} + +/************************************************************************************************************************************** + Introducir minterminos **/ +void minterm2peripheral(int *fun_obj, int tamano, void *evalfit_ptr) +{ + int i, j, a; + + for(i = 0; i < 512; i++) //rellenar con 0 + { + *(int *)(evalfit_ptr + EVALFIT_OBJOFFSET + (i*4)) = 0; + } + + for(i = 0; i < tamano; i++) //insertar 1's en segmento de mem objetivo + { + j=0; + a=fun_obj[i]; + while(a > 31) + { + a -= 32; + j++; + } + *(int *)(evalfit_ptr + EVALFIT_OBJOFFSET + (j*4)) += (1 << (31-a)); + } +} + +/************************************************************************************************************************************** + inicializar periferico **/ +int init_peripheral(int offset_int, int basemem) +{ +/* Variables para periferico*/ +int *aux, base_periferico, *evalfit_ptr; + off_t offset = offset_int; //Direccion base del periferico + base_periferico = (int *)mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, basemem, offset & ~MAP_MASK); + evalfit_ptr = base_periferico + (offset & MAP_MASK); + printf("\r\nPeripheral_ptr: %0x", evalfit_ptr); + if( (int *)evalfit_ptr == (int *)MAP_FAILED) + { printf("error mmap!\n"); + fflush(stdout); + return -1; + } + *(int *)(evalfit_ptr + EVALFIT_CONTROL_OFFSET) = CONTROL_RESET_MASK; //reset + *(int *)(evalfit_ptr + EVALFIT_CONTROL_OFFSET) = 0; + printf("\nDate + Status: %0x\n", *(int *)(evalfit_ptr + EVALFIT_STATUS_OFFSET)); + return evalfit_ptr; +} + +/************************************************************************************************************************************** + cerrar periferico **/ +int close_peripheral(char *evalfit_ptr) +{ + if(munmap(evalfit_ptr, MAP_SIZE)==-1) + perror("munmap"); + printf("Error en unmap() (close_peripheral)\n"); + exit(-1); +} + +/************************************************************************************************************************************** + cambiar endianismo **/ +int big2little(int x) +{ +int y, i, r; +y=0; +r=0; + for(i=0 ; i<=3; i++){ + x = x >> r; + y = y << r; + y = y | (x & 0xFF); + r = 8; + } +return y; +} + +/************************************************************************************************************************************** + crea y evoluciona un cromosoma a partir de una funcion objetivo*/ +evolucionar(struct gen_datos_tipo *gen_datos) +{ +int *generacion, k, a, i, j = 0, tamacromo, vars, aux, *aux_sal, T; +int conta=0, aux1, aux2, *fitness, *fitness2, *entrada, *objetivo, tamaobj, pentarboles, *fitness_sal, fitness_entrada, nivel_max; +char o, *ap, *cromo, *ordenpoblacion, *cromo_sal, *cromo_entrada; +long int tiempo1, tiempo2; +float tiempof1, tiempof2, tiempof3; + +/* Variables para almacenar datos para graficar*/ + int *datos, x, puntos; + char ruta[]="sarsar.dat"; + FILE *fich; +/* datos = malloc(sizeof(datos)*maxgeneraciones*2); if(datos==0) printf("Error en malloc");*/ +/* x=0;*/ + + objetivo = gen_datos -> objetivo; + tamaobj = gen_datos -> tamaobj; + pentarboles = gen_datos -> pentarboles; + tamacromo = gen_datos -> tamacrom; + cromo_sal = gen_datos -> cromo_sal; + fitness_sal = gen_datos -> fitness; + cromo_entrada = gen_datos -> cromo_entrada; + fitness_entrada = gen_datos -> fitness_entrada; + nivel_max = gen_datos -> nivel_max; + vars = gen_datos -> vars; + generacion = gen_datos->generacion; + aux = gen_datos->aux; + aux_sal = gen_datos->aux_sal; + + cromo = malloc(sizeof(cromo) * (poblacion + 2) * LONG_INDIV); if(cromo==0) printf("Error en malloc"); + fitness = malloc(sizeof(fitness) * (poblacion+1)); if(fitness==0) printf("Error en malloc"); + fitness2 = malloc(sizeof(fitness2) * (poblacion+1)); if(fitness2==0) printf("Error en malloc"); + ordenpoblacion = malloc(sizeof(ordenpoblacion) * (poblacion+1)); if(ordenpoblacion==0) printf("Error en malloc"); + + if(gen_datos->en_cromo_entrada == 1) + { + for(i = 0; i < LONG_INDIV; i++ ) + { + *(char *)(cromo + i) = *(char *)(cromo_entrada + i); + } + } + + if(gen_datos->en_cromo_entrada==0) gen_poblacion(cromo, pentarboles, vars, poblacion); + else gen_poblacion(cromo + LONG_INDIV, pentarboles, vars, poblacion-1); + + for(i = 0; i < poblacion; i++) + { + *(ordenpoblacion + i) = i; //se inicializa el stream para el orden poblacional + *(fitness + i) = 100000; + *(fitness2 + i) = 100000; + } + +/** copiar miniterminos a periferico **/ + if(HW_ENABLE == 1) { + minterm2peripheral(objetivo, tamaobj, (int *)(evalfit_ptr1)); + minterm2peripheral(objetivo, tamaobj, (int *)(evalfit_ptr2)); + minterm2peripheral(objetivo, tamaobj, (int *)(evalfit_ptr3)); + minterm2peripheral(objetivo, tamaobj, (int *)(evalfit_ptr4)); + } + +/** Insertar maxcombs y nivel_max **/ + if(HW_ENABLE == 1) { + *(int *)(evalfit_ptr1 + EVALFIT_WREG4) = (COMBS-1) + (nivel_max << 16); + *(int *)(evalfit_ptr2 + EVALFIT_WREG4) = (COMBS-1) + (nivel_max << 16); + *(int *)(evalfit_ptr3 + EVALFIT_WREG4) = (COMBS-1) + (nivel_max << 16); + *(int *)(evalfit_ptr4 + EVALFIT_WREG4) = (COMBS-1) + (nivel_max << 16); + } + o=0; + *generacion = 0; + T = aux >> 16; + do{ + +// cruzar + for(i = ((poblacion*T)/8); i < ((poblacion*(T+1))/8); i=i+4) //salvar los primeros 4 y cruzar + { + cross2point(cromo+INDICE_PADRE1, cromo+INDICE_PADRE2, cromo+(*(ordenpoblacion+i)*LONG_INDIV), cromo+(*(ordenpoblacion+i+1)*LONG_INDIV), pentarboles); + cross2point(cromo+INDICE_PADRE1, cromo+INDICE_PADRE2, cromo+(*(ordenpoblacion+i+2)*LONG_INDIV), cromo+(*(ordenpoblacion+i+3)*LONG_INDIV), pentarboles); + }//cruzar + +// Mutacion + for(i = ((poblacion*(T+1))/8); i < ((poblacion*(T+2))/8); i++) + { + muta_indiv(cromo + INDICE_PADRE1, cromo + ((*(ordenpoblacion + i )) * LONG_INDIV), pentarboles, vars); + } + for(i = ((poblacion*(T+2))/8); i < ((poblacion*(T+3))/8); i++) + { + muta_indiv(cromo + INDICE_PADRE2, cromo + ((*(ordenpoblacion + i )) * LONG_INDIV), pentarboles, vars); + } + +//crear nuevos indiv reemplazar por taras + for(i = ((poblacion*(T+3))/8); i < poblacion; i++) + { + gen_indiv((cromo + ((*(ordenpoblacion + i)) * LONG_INDIV)), pentarboles, vars); + } + +// evaluar cromosomas de poblacion + o=0; +// tiempo1 = get_timestamp(); + for(i = 0; i < poblacion; i=i+4) + { + if(HW_ENABLE == 1) + { + evalfit_hw_init((cromo + (i * LONG_INDIV)), pentarboles, nivel_max, (int *)evalfit_ptr1); + evalfit_hw_init((cromo + ((i+1) * LONG_INDIV)), pentarboles, nivel_max, (int *)evalfit_ptr2); + evalfit_hw_init((cromo + ((i+2) * LONG_INDIV)), pentarboles, nivel_max, (int *)evalfit_ptr3); + evalfit_hw_init((cromo + ((i+3) * LONG_INDIV)), pentarboles, nivel_max, (int *)evalfit_ptr4); + *(fitness + i) = evalfit_hw_wait((cromo + (i * LONG_INDIV)), pentarboles, nivel_max, (int *)evalfit_ptr1); + *(fitness + i+1) = evalfit_hw_wait((cromo + ((i+1) * LONG_INDIV)), pentarboles,nivel_max, (int *)evalfit_ptr2); + *(fitness + i+2) = evalfit_hw_wait((cromo + ((i+2) * LONG_INDIV)), pentarboles,nivel_max, (int *)evalfit_ptr3); + *(fitness + i+3) = evalfit_hw_wait((cromo + ((i+3) * LONG_INDIV)), pentarboles, nivel_max, (int *)evalfit_ptr4); + }else{ + *(fitness + i) = eval_fit_sw((cromo + (i * LONG_INDIV)), objetivo, tamaobj, pentarboles, vars); + *(fitness + i+1) = eval_fit_sw((cromo + ((i+1) * LONG_INDIV)), objetivo, tamaobj, pentarboles, vars); + *(fitness + i+2) = eval_fit_sw((cromo + ((i+2) * LONG_INDIV)), objetivo, tamaobj, pentarboles, vars); + *(fitness + i+3) = eval_fit_sw((cromo + ((i+3) * LONG_INDIV)), objetivo, tamaobj, pentarboles, vars); + } + *(fitness2 + i) = *(fitness + i); + *(fitness2 + i+1) = *(fitness + i+1); + *(fitness2 + i+2) = *(fitness + i+2); + *(fitness2 + i+3) = *(fitness + i+3); + + if(*(fitness + i) < PESO_SALIDA) + { + o++; //incrementar numero de aciertos + } + } +// tiempo2 = get_timestamp(); + x++; + + //seleccionar cromosomas para mutar y cruzar y para eliminar, se realiza una ordenacion en ordenpoblacion, solo se ordena el indice del cromosoma + for(i = 0; i < poblacion; i++) + { + *(ordenpoblacion + i) = i; //se inicializa el stream para el orden poblacional + } + + for(i=0; i < poblacion; i++) + { + for(j=i+1; j < poblacion; j++) + { + if(*(fitness2 + j) < *(fitness2 + i)) + { + aux1 = *(ordenpoblacion + i); + *(ordenpoblacion + i) = *(ordenpoblacion + j); + *(ordenpoblacion + j) = aux1; + aux2 = *(fitness2 + i); + *(fitness2 + i) = *(fitness2 + j); + *(fitness2 + j) = aux2; + } + } + } + + + //Se mide la evolucion del fitness en las generaciones, se saca la media por generacion + aux1 = 0; + for(i = 0; i < poblacion; i++) + { + aux1 = aux1 + *(fitness + i); + } + *(aux_sal + *generacion) = aux1 / poblacion; + *(aux_sal + maxgeneraciones + *generacion) = *fitness2; + + (*generacion)++; + +// for(i=0; i < RESULTADOS; i++) +// { +// printf("\nfit%i: %i ", i, *(fitness+*(ordenpoblacion+i)), *(generacion+*(ordenpoblacion+i))); +// mostrar_indiv(cromo + ( *(ordenpoblacion + i) * LONG_INDIV), pentarboles, vars); +// } + + }while(/* (o < RESULTADOS) && */ (*generacion < maxgeneraciones)); + + for(i = 0; i < RESULTADOS; i++) + { + for(j=0; j< LONG_INDIV;j++) + { + *(cromo_sal + (i*LONG_INDIV) + j) = *(cromo + (*(ordenpoblacion + i)*LONG_INDIV) + j); + } + *(fitness_sal + i) = *(fitness + *(ordenpoblacion + i)); + } + + free(cromo); + free(fitness); + free(fitness2); + free(ordenpoblacion); +} + diff --git a/Examples/ehw4/src/genetic.h b/Examples/ehw4/src/genetic.h new file mode 100644 index 0000000..3914e13 --- /dev/null +++ b/Examples/ehw4/src/genetic.h @@ -0,0 +1,126 @@ + +/** Genetic definitions **/ +#define HW_ENABLE 1 //cambiar en sintesishw_server.h habilitar hw, 0 se hace por SW +#define PAR_ONLYFIT 0 //paralelizacion, 0 ALGORITMO ENTERO, 1 SOLO FITNESS + +#define FUNCIONES 4 +#define COMBS (int) pow(2,vars) +#define FUNCOMBS (int) pow(FUNCIONES + 1, 3) +#define FUN_NOT 0 +#define FUN_AND 1 +#define FUN_XOR 2 +#define FUN_OR 3 +#define YES FUNCIONES +#define NOVAR vars +#define PESO_SALIDA 100 +#define PESO_PUERTAS 5 +#define PESO_NIVELES 0 + +#define RESULTADOS 2 + +/* Numero de generaciones en el que se amplia la logitud del cromosoma*/ +#define UMBRAL_GENERACION (int) pow(3, pentarboles) * 33 +#define MAX_PENTARBOLES 16 + +#define ARBOLES 5 +#define LONG_ARBOL 8 + +int nivel2[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; +int nivel3[]={0,0,1,1,1,2,2,2,2,3,3, 3, 3, 4, 4, 4}; +int nivel4[]={0,0,0,0,0,1,1,1,1,1,1, 1, 1, 1, 1, 1}; +int nivel5[]={0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0}; + +#define nivel1 pentarboles * 4 +#define ARBOLES_INDIV (int)(nivel1 + *(nivel2+pentarboles) + *(nivel3+pentarboles) + *(nivel4+pentarboles) + *(nivel5+pentarboles)) +#define LONG_INDIV (int)(ARBOLES_INDIV * LONG_ARBOL) + +#define INDICE_PADRE1 ((*ordenpoblacion) * LONG_INDIV) +#define INDICE_PADRE2 ((*(ordenpoblacion+1)) * LONG_INDIV) + +#define INDICE_TARA1 ((*(ordenpoblacion+poblacion-1)) * LONG_INDIV) +#define INDICE_TARA2 ((*(ordenpoblacion+poblacion-2)) * LONG_INDIV) +#define INDICE_TARA3 ((*(ordenpoblacion+poblacion-3)) * LONG_INDIV) +#define INDICE_TARA4 ((*(ordenpoblacion+poblacion-4)) * LONG_INDIV) + + +/************************** peripheral Definitions ***************************/ + +#define USR_REGS 0x10 +#define MAP_SIZE 0x4000Ul +#define MAP_MASK (MAP_SIZE - 1) + +#define DONE_MASK 0x1 +#define ERRORS_MASK 0xFFFF + +/** CONTROL REGISTERS **/ +#define EVALFIT_REGBASE_OFFSET 0 + +#define EVALFIT_CONTROL_OFFSET EVALFIT_REGBASE_OFFSET + 0 +#define CONTROL_RESET_MASK 0x80000000 +#define CONTROL_START_MASK 0x40000000 + +#define EVALFIT_STATUS_OFFSET EVALFIT_REGBASE_OFFSET + 0 +#define EVALFIT_SRCADDR_OFFSET EVALFIT_REGBASE_OFFSET + 4 +#define EVALFIT_DSTADDR_OFFSET EVALFIT_REGBASE_OFFSET + 8 +#define EVALFIT_TRANSFERSIZE_OFFSET EVALFIT_REGBASE_OFFSET + 12 +#define EVALFIT_REG_OFFSET EVALFIT_REGBASE_OFFSET + 16 + +/** WRITE REGISTERS **/ +#define EVALFIT_WREG4 (EVALFIT_REGBASE_OFFSET + (4*4)) +#define EVALFIT_WREG5 (EVALFIT_REGBASE_OFFSET + (4*5)) +#define EVALFIT_wREG6 (EVALFIT_REGBASE_OFFSET + (4*6)) +#define EVALFIT_wREG7 (EVALFIT_REGBASE_OFFSET + (4*7)) +#define EVALFIT_wREG8 (EVALFIT_REGBASE_OFFSET + (4*8)) + +/** READ REGISTERS **/ +#define EVALFIT_RDREG0 (EVALFIT_REGBASE_OFFSET) +#define EVALFIT_RDREG1 (EVALFIT_REGBASE_OFFSET + (4*1)) +#define EVALFIT_RDREG2 (EVALFIT_REGBASE_OFFSET + (4*2)) +#define EVALFIT_RDREG3 (EVALFIT_REGBASE_OFFSET + (4*3)) +#define EVALFIT_RDREG4 (EVALFIT_REGBASE_OFFSET + (4*4)) +#define EVALFIT_RDREG5 (EVALFIT_REGBASE_OFFSET + (4*5)) +#define EVALFIT_RDREG6 (EVALFIT_REGBASE_OFFSET + (4*6)) +#define EVALFIT_RDREG7 (EVALFIT_REGBASE_OFFSET + (4*7)) +#define EVALFIT_RDREG8 (EVALFIT_REGBASE_OFFSET + (4*8)) +/** MEMORY **/ +#define EVALFIT_MEMOFFSET 0x1000 +#define EVALFIT_OBJOFFSET EVALFIT_MEMOFFSET + (0x40 * 8) + +/** CROMOSOMA **/ +#define CROMO_NIVEL_OFFSET + +/* Variables globales */ +char *funlut_ap, *puertas_ap; +void *evalfit_ptr1, *evalfit_ptr4, *evalfit_ptr3, *evalfit_ptr2; +int maxgeneraciones, poblacion; + + +typedef long long timestamp_t; +static timestamp_t + get_timestamp () +{ + struct timeval now; + gettimeofday (&now, NULL); + return now.tv_usec + (timestamp_t)now.tv_sec *1000000 ; +} + +struct gen_datos_tipo +{ + int *objetivo; + int tamaobj; + int pentarboles; + int vars; + int tamacrom; + int maxgen; + char *cromo_sal; + int *fitness; + char *cromo_entrada; + int fitness_entrada; + int nivel_max; + int en_cromo_entrada; + int *generacion; + int *tiempo; + int aux; + int *aux_sal; +}; + diff --git a/Examples/ehw4/src/puertas.dat b/Examples/ehw4/src/puertas.dat new file mode 100644 index 0000000000000000000000000000000000000000..0e10ef4fb9139bcbf17be04327a4b4c9386f7906 GIT binary patch literal 125 ecmZQ(W@csrVq}5|2pG}Cz+5sV7_k5b5C8yAQ2`kM literal 0 HcmV?d00001 diff --git a/Examples/ehw4/src/sintesishw.h b/Examples/ehw4/src/sintesishw.h new file mode 100644 index 0000000..d6d6d5e --- /dev/null +++ b/Examples/ehw4/src/sintesishw.h @@ -0,0 +1,97 @@ +/** Genetic definitions **/ + +#define HW_ENABLE 0 //habilitar hw, 0 se hace por SW +#define VARS 8 +#define FUNCIONES 4 +#define COMBS (int) pow(2,VARS) +#define FUNCOMBS (int) pow(FUNCIONES + 1, 3) +#define FUN_NOT 0 +#define FUN_AND 1 +#define FUN_XOR 2 +#define FUN_OR 3 +#define YES FUNCIONES +#define NOVAR VARS +#define PESO_SALIDA 1 +#define PESO_PUERTAS 1 + +#define MAXGENERACIONES 32 +#define RESULTADOS 4 + +/* Numero de generaciones en el que se amplia la logitud del cromosoma*/ +#define UMBRAL_GENERACION (int) pow(3, pentarboles) * 5000 +#define MAX_PENTARBOLES 16 + +#define POBLACION 4 +#define ARBOLES 5 +#define LONG_ARBOL 8 + + + +/* +POBLACION define el numero de individuos. minimo 6. 2 padres 4 taras +ARBOLES define el numero de arboles en un individuo. Cada arbol tiene 3 funciones 4 variables. +INDICES_XXX define el desplazamiento de un individuo en el cromosoma completo de la poblacion, cromo +*/ + +#define nivel1 pentarboles * 4 +#define ARBOLES_INDIV (int)(nivel1 + nivel2(pentarboles) + nivel3(pentarboles) + nivel4(pentarboles) + nivel5(pentarboles)) +#define LONG_INDIV (int)(ARBOLES_INDIV * LONG_ARBOL) + +#define INDICE_PADRE1 ((*ordenpoblacion) * LONG_INDIV) +#define INDICE_PADRE2 ((*(ordenpoblacion+1)) * LONG_INDIV) + +#define INDICE_TARA1 ((*(ordenpoblacion+POBLACION-1)) * LONG_INDIV) +#define INDICE_TARA2 ((*(ordenpoblacion+POBLACION-2)) * LONG_INDIV) +#define INDICE_TARA3 ((*(ordenpoblacion+POBLACION-3)) * LONG_INDIV) +#define INDICE_TARA4 ((*(ordenpoblacion+POBLACION-4)) * LONG_INDIV) + + + +/************************** peripheral Definitions ***************************/ +#define EVALFIT_PHYSBASE 0xcd800000 +#define USR_REGS 0x10 +#define MAP_SIZE 0x4000Ul +#define MAP_MASK (MAP_SIZE - 1) + +#define DONE_MASK 0x1 +#define ERRORS_MASK 0xFFFF + + + +/** CONTROL REGISTERS **/ +#define EVALFIT_REGBASE_OFFSET 0 + +#define EVALFIT_CONTROL_OFFSET EVALFIT_REGBASE_OFFSET + 0 +#define CONTROL_RESET_MASK 0x80000000 +#define CONTROL_START_MASK 0x40000000 + +#define EVALFIT_STATUS_OFFSET EVALFIT_REGBASE_OFFSET + 0 +#define EVALFIT_SRCADDR_OFFSET EVALFIT_REGBASE_OFFSET + 4 +#define EVALFIT_DSTADDR_OFFSET EVALFIT_REGBASE_OFFSET + 8 +#define EVALFIT_TRANSFERSIZE_OFFSET EVALFIT_REGBASE_OFFSET + 12 +#define EVALFIT_REG_OFFSET EVALFIT_REGBASE_OFFSET + 16 + +/** WRITE REGISTERS **/ +#define EVALFIT_WREG4 (EVALFIT_REGBASE_OFFSET + (4*4)) +#define EVALFIT_WREG5 (EVALFIT_REGBASE_OFFSET + (4*5)) +#define EVALFIT_wREG6 (EVALFIT_REGBASE_OFFSET + (4*6)) +#define EVALFIT_wREG7 (EVALFIT_REGBASE_OFFSET + (4*7)) +#define EVALFIT_wREG8 (EVALFIT_REGBASE_OFFSET + (4*8)) + +/** READ REGISTERS **/ +#define EVALFIT_RDREG0 (EVALFIT_REGBASE_OFFSET) +#define EVALFIT_RDREG1 (EVALFIT_REGBASE_OFFSET + (4*1)) +#define EVALFIT_RDREG2 (EVALFIT_REGBASE_OFFSET + (4*2)) +#define EVALFIT_RDREG3 (EVALFIT_REGBASE_OFFSET + (4*3)) +#define EVALFIT_RDREG4 (EVALFIT_REGBASE_OFFSET + (4*4)) +#define EVALFIT_RDREG5 (EVALFIT_REGBASE_OFFSET + (4*5)) +#define EVALFIT_RDREG6 (EVALFIT_REGBASE_OFFSET + (4*6)) +#define EVALFIT_RDREG7 (EVALFIT_REGBASE_OFFSET + (4*7)) + +/** MEMORY **/ +#define EVALFIT_MEMOFFSET 0x1000 +#define EVALFIT_OBJOFFSET EVALFIT_MEMOFFSET + (0x40 * 8) + +/** CROMOSOMA **/ +#define CROMO_NIVEL_OFFSET + diff --git a/Examples/ehw4/src/sintesishw_client.c b/Examples/ehw4/src/sintesishw_client.c new file mode 100644 index 0000000..2f89fc4 --- /dev/null +++ b/Examples/ehw4/src/sintesishw_client.c @@ -0,0 +1,461 @@ +/********************************************************************************************************* +** Programa para probar la sintesis combinacional mediante programacion genetica, +** se usan sockets para repartir carga de trabajo a otros clientes +** Se usa periferico evalfit del proyecto ehw3 +** se aceleran 5 arboles, que en el presente codigo se llama pentarbol +** compilar con math.h -lm +** compilar con threads: -lpthread +** gcc sintesishw_client.c -lm -lpthread -o sintesishw_client_ppc +** ejecutar: +** ./sintesishw_client_386 vars poblacion generaciones pentarboles sar.dat sar2.dat +** +**********************************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/************************************************************************************************************************************** + */ +create_connect_socket(char *addr, int *fd_ap) +{ + int fd; + struct sockaddr_in input_addr; + struct sockaddr_in server; + if (inet_aton(addr, &input_addr.sin_addr)==-1) + { perror("inet_aton"); + exit(-1); + } + + if ((fd=socket(AF_INET, SOCK_STREAM, 0))==-1){ + printf("socket() error\n"); + exit(-1); + } + + server.sin_family = AF_INET; + server.sin_port = htons(PORT); + server.sin_addr = input_addr.sin_addr; + bzero(&(server.sin_zero),8); + + if(connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr))==-1) + { + // printf("connect() error en %s\n",addr); + perror("connect"); + exit(-1); + } +/* printf(".");*/ + *fd_ap = fd; +} + + +rx_cromo(int fd, void *data_socket_rx_ap, char *cromo_sal, int *fitness, int pentarboles, int *generacion, int *tiempo, int *aux_sal) +{ +void *ap1; +int i, j, numbytes_rx; +int nivel2[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; +int nivel3[]={0,0,1,1,1,2,2,2,2,3,3, 3, 3, 4, 4, 4}; +int nivel4[]={0,0,0,0,0,1,1,1,1,1,1, 1, 1, 1, 1, 1}; +int nivel5[]={0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0}; + + + if ((numbytes_rx=recv(fd,data_socket_rx_ap,MAXDATASIZE,0)) == -1){ + printf("Error en recv() \n"); + perror("recv"); + exit(-1); + } + ap1 = data_socket_rx_ap; +/* printf("Rx:%i ",ntohl(*(int *)ap1));*/ + ap1 = ap1 + 4; + for(i=0; i < RESULTADOS ;i++) + { + for(j=0; j < LONG_INDIV ;j++) + { + *(cromo_sal + j + (LONG_INDIV*i)) = *(char *)ap1; + ap1 ++; + } + *(fitness + i) = ntohl(*(int *)ap1) & 0xFFFF; + *(generacion + i) = ntohl(*(int *)ap1) >> 16; + ap1 = ap1 + 4; + *(tiempo+i) = ntohl(*(int *)ap1); + ap1 = ap1 + 4; + } + for(i = 0; i < maxgeneraciones*2 ;i++) + { + *(aux_sal + i) = ntohl(*(int *)ap1); + ap1 = ap1 + 4; + } +} + +tx_cromo(struct gen_datos_tipo *gen_datos, int fd) +{ +void *data_socket_tx_ap, *ap1; +int *objetivo, i, numbytes_tx; + + data_socket_tx_ap = malloc((gen_datos->tamaobj)*sizeof(int) + gen_datos->tamacrom + 0xFF); + ap1= data_socket_tx_ap; + + *(int *)ap1 = htonl(gen_datos->tamaobj | (maxgeneraciones << 16)); + ap1 = ap1 + 4; + objetivo = gen_datos->objetivo; + for(i=0; i < (gen_datos->tamaobj); i++) + { + *(int *)ap1 = htonl(objetivo[i]); + ap1 = ap1 + 4; + } + *(int *)ap1 = htonl(gen_datos->pentarboles | (gen_datos->vars << 16)); + ap1 = ap1 + 4; + *(int *)ap1 = htonl(gen_datos->tamacrom | (poblacion << 16)); + ap1 = ap1 + 4; + + for(i = 0; i < (gen_datos->tamacrom); i++) + { + *(char *)(ap1) = *(char *)(gen_datos->cromo_entrada + i); + ap1 = ap1 + 1; + } + + *(int *)ap1 = htonl(gen_datos->fitness_entrada); //fitness de entrada? + ap1 = ap1 + 4; + *(int *)ap1 = htonl((gen_datos->en_cromo_entrada<<16) | gen_datos->nivel_max); + ap1 = ap1 + 4; + *(int *)ap1 = htonl(gen_datos->aux); //datos varios + ap1 = ap1 + 4; + *(int *)ap1 = htonl(0xa55a9669); //datos varios + ap1 = ap1 + 4; + numbytes_tx = ap1 - data_socket_tx_ap; + send(fd, data_socket_tx_ap, numbytes_tx ,0); //enviar + free(data_socket_tx_ap); + +} + + + +/************************************************************************************************************************************** + crea una poblacion, y envia a placas para evolucionar */ +iniciar_evol(struct gen_datos_tipo *gen_datos) +{ +int *generacion, k, a, i, j = 0, vars; +int conta=0, aux1, aux2, *fitness, *fitness2, *entrada, *objetivo, tamaobj, pentarboles, maxgens, *fitness_sal, fitness_entrada, nivel_max, *aux_sal; +char o, *ap, *cromo, *ordenpoblacion, *cromo_sal, *cromo_entrada; +int *tiempo; +int nivel2[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; +int nivel3[]={0,0,1,1,1,2,2,2,2,3,3, 3, 3, 4, 4, 4}; +int nivel4[]={0,0,0,0,0,1,1,1,1,1,1, 1, 1, 1, 1, 1}; +int nivel5[]={0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0}; + +/* variables para sockets */ + int fds[8],fd1, fd2, fd3, fd4, fd5, fd6, fd7, fd8, numbytes_tx, numbytes_rx; /* ficheros descriptores para sockets*/ + void *data_socket_rx_ap; + char server[][16] = {IP0, IP1, IP2, IP3, IP4, IP5, IP6, IP7}; + + pentarboles = gen_datos->pentarboles; + vars = gen_datos->vars; + generacion = gen_datos->generacion; + tiempo = gen_datos->tiempo; + aux_sal = gen_datos->aux_sal; + + cromo = malloc(sizeof(cromo) * (poblacion + 2) * LONG_INDIV); if(cromo==0) printf("Error en malloc"); + fitness = malloc(sizeof(fitness) * (poblacion+1)); if(fitness==0) printf("Error en malloc"); + fitness2 = malloc(sizeof(fitness2) * (poblacion+1)); if(fitness2==0) printf("Error en malloc"); + ordenpoblacion = malloc(sizeof(ordenpoblacion) * (poblacion+1)); if(ordenpoblacion==0) printf("Error en malloc"); + + for(i=0; i < nodos; i++) //enviar a nodos + { + create_connect_socket(server[i], &fds[i]); + } + +/* preparar socket para recibir */ + data_socket_rx_ap = malloc(10000); + +if(PAR_ONLYFIT==1) +{ + gen_poblacion(cromo, pentarboles, vars); + + // cruzar + for(i = ((poblacion*1)/8); i < ((poblacion*2)/8); i=i+4) //salvar los primeros 4 y cruzar + { + cross2point(cromo+i*LONG_INDIV, cromo + i*LONG_INDIV, cromo+((i)*LONG_INDIV), cromo+((i+1)*LONG_INDIV), pentarboles); + cross2point(cromo+i*LONG_INDIV, cromo + i*LONG_INDIV, cromo+((i+2)*LONG_INDIV), cromo+((i+3)*LONG_INDIV), pentarboles); + }//cruzar + + // Mutacion + for(i = ((poblacion*2)/8); i < ((poblacion*3)/8); i++) + { + muta_indiv(cromo + i*LONG_INDIV, cromo + ((( i )) * LONG_INDIV), pentarboles, vars); + } + for(i = ((poblacion*3)/8); i < ((poblacion*4)/8); i++) + { + muta_indiv(cromo + i*LONG_INDIV, cromo + ((( i )) * LONG_INDIV), pentarboles, vars); + } + + //crear nuevos indiv reemplazar por taras + for(i = ((poblacion*4)/8); i < poblacion; i++) + { + gen_indiv((cromo + ((( i)) * LONG_INDIV)), pentarboles, vars); + } + + *generacion++; +} + + gen_datos->tamacrom = LONG_INDIV; + +for(j=0;j<1;j++) +{ + for(i=0; icromo_sal; + + for(i=0; ifitness+(RESULTADOS*i), pentarboles,generacion + (RESULTADOS*i),tiempo+(RESULTADOS*i), aux_sal+(maxgeneraciones*2*i)); + } + +} + + free(cromo); + free(fitness); + free(fitness2); + free(ordenpoblacion); + free(data_socket_rx_ap); + for(i=0; i b)z=1; if(a < b)z=2; if(a == b)z=4; + if((z & 0x4) != 0 ) + { + objetivo[tamaobj] = i; + printf("%i ",objetivo[tamaobj]); + tamaobj++; + } + i++; + } + } +// printf("Tama:%i ",tamaobj); + +/* Tabla para las LUT*/ + f1 = fopen("funlut.dat","r"); + if(f1 == NULL){ + printf("\nError de lectura de archivo!"); + return 0;} + + fseek (f1, 0, SEEK_END); + size1 = ftell(f1); + funlut_ap = malloc(size1); if(funlut_ap==0) printf("Error en malloc"); + rewind (f1); + fread(funlut_ap,1,size1,f1); + fclose(f1); + + puntos = 16; /*numero de puntos para la grafica*/ + datos = malloc(sizeof(datos)*puntos*3); if(datos==0) printf("Error en malloc"); + fich=fopen(output_file_name,"wb"); + datos2 = malloc(sizeof(datos2) * maxgeneraciones * p * nodos); if(datos2==0) printf("Error en malloc"); + fich2=fopen(output_file_fitness_name,"wb"); + + cromo_sal1 = malloc(sizeof(cromo_sal1) * RESULTADOS * LONG_INDIV * nodos); if(cromo_sal1==0) printf("Error en malloc"); + fitness1 = malloc(sizeof(fitness1) * RESULTADOS * nodos); if(fitness1==0) printf("Error en malloc"); + cromo_sal2 = malloc(sizeof(cromo_sal2) * RESULTADOS * LONG_INDIV * nodos); if(cromo_sal2==0) printf("Error en malloc"); + fitness2 = malloc(sizeof(fitness2) * RESULTADOS * nodos); if(fitness2==0) printf("Error en malloc"); + cromo_sal2 = malloc(sizeof(cromo_sal2) * RESULTADOS * LONG_INDIV * nodos); if(cromo_sal2==0) printf("Error en malloc"); + generacion = malloc(sizeof(generacion)* RESULTADOS * nodos); if(generacion==0) printf("Error en malloc"); + tiempo = malloc(sizeof(tiempo)* RESULTADOS * nodos); if(tiempo==0) printf("Error en malloc"); + cromo_entrada = malloc(sizeof(cromo_entrada)* LONG_INDIV * m); if(cromo_entrada==0) printf("Error en malloc"); + orderesult = malloc(sizeof(orderesult) * nodos*RESULTADOS); if(orderesult==0) printf("Error en malloc"); + aux_sal = malloc(sizeof(aux_sal) * nodos * maxgeneraciones * 2); if(aux_sal==0) printf("Error en malloc"); + + data_struct_ap1->objetivo = objetivo; + data_struct_ap1->tamaobj = tamaobj; + data_struct_ap1->pentarboles = pentarboles; + data_struct_ap1->maxgen = maxgeneraciones; + data_struct_ap1->cromo_sal = cromo_sal1; + data_struct_ap1->fitness = fitness1; + data_struct_ap1->cromo_entrada = cromo_entrada; + data_struct_ap1->fitness_entrada = 0; + data_struct_ap1->nivel_max = nivel_max; + data_struct_ap1->vars= vars; + data_struct_ap1->en_cromo_entrada = 0; + data_struct_ap1->generacion = generacion; + data_struct_ap1->tiempo = tiempo; + data_struct_ap1->aux = aux; + data_struct_ap1->aux_sal = aux_sal; + +/* printf("\npentarboles:%i nivel_max%i ", pentarboles ,nivel_max);*/ +/* fflush(stdout); */ + +/* Iniciar evolucion */ + + x = 0; + fflush(stdout); + for(k = 0; k < iteraciones ; k++) + { + tiempo1 = get_timestamp(); + iniciar_evol(data_struct_ap1); + tiempo2 = get_timestamp(); + *tiempo = tiempo2 - tiempo1; + tiempof2 = *tiempo; + tiempof = tiempof2/(1000000); +// printf("\n%i %i %i %5f",nodos, vars, poblacion_total, tiempof); + fprintf(fich, "\n%i %i %i %5f",nodos, vars, poblacion_total, tiempof); + + for(i = 0; i < nodos*RESULTADOS; i++) //Organizar lo q llego, ¡solo se indexa orderesult, que dice en q orden estan los cromosomas! + { + *(orderesult + i) = i; //se inicializa el stream para el orden + } + + for(i=0; i< nodos*RESULTADOS; i++) + { + for(j=i+1; j< nodos*RESULTADOS; j++) + { + if(*(fitness1 + j) < *(fitness1 + i)) + { + aux1 = *(orderesult + i); + *(orderesult + i) = *(orderesult + j); + aux2 = *(fitness1 + i); + *(fitness1 + i) = *(fitness1 + j); + *(orderesult + j) = aux1; + *(fitness1 + j) = aux2; + aux1 = *(generacion + i); + *(generacion + i) = *(generacion + j); + *(generacion + j) = aux1; + } + } + } + + for(i = 0; i < maxgeneraciones; i=i+maxgeneraciones) //revisar mediciones + { + aux1 = 0; + aux2 = 0; + for(j = 0; j < nodos; j++) + { + aux1 = aux1 + *(aux_sal + (maxgeneraciones * 2 * j) + i); + aux2 = aux2 + *(aux_sal + (maxgeneraciones * 2 * j) + maxgeneraciones + i); + } + aux1 = aux1 / nodos; + aux2 = aux2 / nodos; + if((x&(((iteraciones*p)/puntos)-1)) == 0x0) + fprintf(fich2, "%i %i %i\n",(k*p)+i, aux1, aux2); + +// printf("%i %i %i %i\n",(k*p)+i, aux1, aux2, T); + } + + for(i = 0; i < LONG_INDIV; i++ ) + { + *(char *)(cromo_entrada + i) = *(char *)(cromo_sal1 + (*(orderesult)*LONG_INDIV) + i); + } + data_struct_ap1->en_cromo_entrada = 1; + x = x + p; + float1 = k; + float2 = iteraciones; + Tfloat = (float1/float2)*4; + T = 1 + (int)Tfloat; + aux = (T << 16) | p; + data_struct_ap1->aux = aux; + } + + for(i=0; i < RESULTADOS-1 ;i++) + { + printf("\nfit%i:%i gnrcn:%i ", i, *(fitness1), *(generacion + *(orderesult + i))); + mostrar_indiv(cromo_sal1 + ( *orderesult * LONG_INDIV ), pentarboles, vars); + } + + x++; + + free(cromo_sal1); + free(fitness1); + free(cromo_sal2); + free(fitness2); + free(cromo_entrada); + free(orderesult); + free(generacion); + free(tiempo); + free(aux_sal); + +fclose(fich); +fclose(fich2); + +free(datos); +free(datos2); +free(funlut_ap); + +return 0; +} diff --git a/Examples/ehw4/src/sintesishw_client.h b/Examples/ehw4/src/sintesishw_client.h new file mode 100644 index 0000000..7a14ada --- /dev/null +++ b/Examples/ehw4/src/sintesishw_client.h @@ -0,0 +1,64 @@ + +/** Genetic definitions **/ +#define PAR_ONLYFIT 0 //paralelizacion, 0 ALGORITMO ENTERO, 1 SOLO FITNESS + +#define RESULTADOS 2 + +/* Numero de generaciones en el que se amplia la logitud del cromosoma*/ + +#define ARBOLES 5 +#define LONG_ARBOL 8 + +#define nivel1 pentarboles * 4 +#define ARBOLES_INDIV (int)(nivel1 + *(nivel2+pentarboles) + *(nivel3+pentarboles) + *(nivel4+pentarboles) + *(nivel5+pentarboles)) +#define LONG_INDIV (int)(ARBOLES_INDIV * LONG_ARBOL) + +//sockets defs +#define PORT 3550 /* El puerto que sera abierto */ +#define BACKLOG 2 /* El numero de conexiones permitidas */ +#define MAXDATASIZE 10000 /* El numero maximo de datos en bytes */ +#define IP0 "192.168.0.4" +#define IP1 "192.168.0.6" +#define IP2 "192.168.0.7" +#define IP3 "192.168.0.8" +#define IP4 "192.168.0.9" +#define IP5 "192.168.0.10" +#define IP6 "192.168.0.11" +#define IP7 "192.168.0.12" + +//#define IP0 "193.147.52.150" +//#define IP1 "193.147.52.139" + +/* Variables globales */ +char *funlut_ap, *puertas_ap; +void *evalfit_ptr1, *evalfit_ptr4, *evalfit_ptr3, *evalfit_ptr2; +int maxgeneraciones, poblacion, nodos; + +typedef long long timestamp_t; +static timestamp_t + get_timestamp () +{ + struct timeval now; + gettimeofday (&now, NULL); + return now.tv_usec + (timestamp_t)now.tv_sec *1000000 ; +} + +struct gen_datos_tipo +{ + int *objetivo; + int tamaobj; + int pentarboles; + int vars; + int tamacrom; + int maxgen; + char *cromo_sal; + int *fitness; + char *cromo_entrada; + int fitness_entrada; + int nivel_max; + int en_cromo_entrada; + int *generacion; + int *tiempo; + int aux; + int *aux_sal; +}; diff --git a/Examples/ehw4/src/sintesishw_server.c b/Examples/ehw4/src/sintesishw_server.c new file mode 100644 index 0000000..3a0d9d8 --- /dev/null +++ b/Examples/ehw4/src/sintesishw_server.c @@ -0,0 +1,283 @@ +/********************************************************************************************************* +** Programa para probar la sintesis combinacional mediante programacion genetica, +** se usan sockets para repartir carga de trabajo a otros clientes +** Se usa periferico evalfit del proyecto ehw3 +** se aceleran 5 arboles, que en el presente codigo se llama pentarbol +** compilar con math.h -lm +** compilar con threads: -lpthread +** powerpc-405-linux-gnu-gcc sintesishw_server.c -lm -lpthread -o sintesishw_server_ppc +** +** +**********************************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/************************************************************************************************************************************** + crea socket */ +int crear_socket() +{ +int fd; +struct sockaddr_in server; + + if ((fd=socket(AF_INET, SOCK_STREAM, 0)) == -1 ) /* Crear socket */ + { + perror("socket"); + exit(-1); + } + server.sin_family = AF_INET; + server.sin_port = htons(PORT); /* cambiar endianismo */ + server.sin_addr.s_addr = INADDR_ANY; /* INADDR_ANY coloca nuestra direccion IP */ + bzero(&(server.sin_zero),8); /* escribimos ceros en el resto de la estructura */ + if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&server,sizeof(struct sockaddr)) == -1) /* permite reutilizar el puerto */ + { + perror("setsockopt"); + exit(1); + } + if(bind(fd,(struct sockaddr*) & server, sizeof(struct sockaddr))==-1) //se asigna el socket + { + perror("bind"); + exit(EXIT_FAILURE); + } +return fd; +} + + +/*******************************************************************************************************************************/ +/*******************************************************************************************************************************/ +/*******************************************************************************************************************************/ +/*******************************************************************************************************************************/ + +int main() +{ + int k, a, i, j = 0, error, vars = 4, *tiempo; + int conta=0, aux1, aux2, pentarboles, *fitness1, *fitness2, *entrada, *generacion, aux, *aux_sal; + char o, *ap, *valor_devuelto;; + char *cromo_sal1, *cromo_sal2, *cromo_entrada, *cromo_ap_aux; + int objetivo[8192];//= {0,254,123,16,87,56,34,76,89,155,199}; + struct gen_datos_tipo data_struct1, data_struct2; + struct gen_datos_tipo *data_struct_ap1, *data_struct_ap2; + +int nivel2[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; +int nivel3[]={0,0,1,1,1,2,2,2,2,3,3, 3, 3, 4, 4, 4}; +int nivel4[]={0,0,0,0,0,1,1,1,1,1,1, 1, 1, 1, 1, 1}; +int nivel5[]={0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0}; + +/* Variables para tablas de lut*/ + FILE *f1, *f2; + int size1, size2; + +/* Variables para los sockets */ + int fd, fd2, numbytes; /* punteros para sockets */ + struct sockaddr_in server; + struct sockaddr_in client; + void *data_socket_rx_ap, *data_socket_tx_ap, *ap1; + int sin_size; + +/*para periferico*/ + int basemem; + + srand ( (time(NULL)) ); + +/* Tabla para las LUT*/ + f1 = fopen("funlut.dat","r"); + if(f1 == NULL){ printf("\nError de lectura de archivo!");return 0;} + fseek (f1, 0, SEEK_END); + size1 = ftell(f1); + funlut_ap = malloc(size1); if(funlut_ap==0) printf("Error en malloc"); + rewind (f1); + fread(funlut_ap,1,size1,f1); + fclose(f1); + + f2 = fopen("puertas.dat","r"); + if(f2 == NULL){ printf("\nError de lectura de archivo!");return 0;} + fseek (f2, 0, SEEK_END); + size2 = ftell(f2); + puertas_ap = malloc(size2); if(puertas_ap==0) printf("Error en malloc"); + rewind (f2); + fread(puertas_ap,1,size2,f2); + fclose(f2); + + basemem = open("/dev/mem", (O_RDWR | O_SYNC)); //abrir dispositivo memoria para mapear dir del periferico + if(basemem == -1) + { printf("Error al abrir /dev/mem \n"); + return -1;} + +/** iniciar periferico **/ + if(HW_ENABLE == 1){ + evalfit_ptr1 = (int *)init_peripheral(EVALFIT_PHYSBASE1, basemem); + evalfit_ptr2 = (int *)init_peripheral(EVALFIT_PHYSBASE2, basemem); + evalfit_ptr3 = (int *)init_peripheral(EVALFIT_PHYSBASE3, basemem); + evalfit_ptr4 = (int *)init_peripheral(EVALFIT_PHYSBASE4, basemem); + } + data_struct_ap1 = &data_struct1; + data_struct_ap2 = &data_struct2; + +/* preparar socket para recibir */ + data_socket_rx_ap = malloc(100000); + data_socket_tx_ap = malloc(100000); + fd = crear_socket(); + if(listen(fd, BACKLOG) == -1) + { printf("error en listen()\n"); + exit(-1); + } + + //int err, sndsize=8192; + //err = setsockopt(fd2, SOL_SOCKET, SO_RCVBUF, (char *)&sndsize, (int)sizeof(sndsize)); + + while(1) + { + sin_size=sizeof(struct sockaddr_in); + if ((fd2 = accept(fd,(struct sockaddr *)&client, &sin_size))==-1) /* llamada a accept() */ + { + printf("error en accept()\n"); + exit(-1); + } +/* printf("Se obtuvo una conexion desde %s\n", inet_ntoa(client.sin_addr) ); //mostrara la IP del cliente QUITAR PARA GANAR VELOCIDAD*/ + + numbytes=0; + do + { + if ((aux1=recv(fd2,data_socket_rx_ap+numbytes,8192,0)) == -1){ /* recibir datos del cliente*/ + perror("recv"); + printf("Error en recv() \n"); + exit(-1); + } + numbytes = numbytes+aux1; + }while(*(int *)(data_socket_rx_ap+numbytes-4)!=htonl(0xa55a9669)); + + ap1 = data_socket_rx_ap; /* Cargar datos en la estructura para la evolucion */ + data_struct_ap1->tamaobj = htonl(*(int *)ap1) & 0xFFFF; + maxgeneraciones = htonl(*(int *)ap1) >> 16; +// printf("\ntama obj:%0x maxgens:%i numbytes:%i-- ", data_struct_ap1->tamaobj, maxgeneraciones,numbytes); + fflush(stdout); + ap1 = ap1 + 4; + for(i=0;i < (data_struct_ap1->tamaobj); i++) + { + objetivo[i] =htonl(*(int *)ap1); //XX +// printf("obj:%i %i ",i,objetivo[i]); + ap1 = ap1 + 4; + } + data_struct_ap1->objetivo = objetivo; + data_struct_ap1->pentarboles = htonl(*(int *)ap1) & 0XFF; + pentarboles = data_struct_ap1->pentarboles; + vars = htonl(*(int *)ap1) >> 16; + data_struct_ap1->vars = vars; + ap1 = ap1 + 4; + data_struct_ap1->tamacrom = htonl(*(int *)ap1) & 0xFFFF; + poblacion = htonl(*(int *)ap1) >> 16; +// printf("\ntamacrom:%0x poblacion:%i vars:%i pentarboles:%i maxgeneraciones:%i ", data_struct_ap1->tamacrom, poblacion,vars,pentarboles,maxgeneraciones); + ap1 = ap1 + 4; + cromo_entrada = malloc(sizeof(cromo_entrada) * RESULTADOS * LONG_INDIV); if(cromo_entrada==0) printf("Error en malloc"); + data_struct_ap1->cromo_entrada = cromo_entrada; + + for(i = 0; i < (data_struct_ap1 -> tamacrom); i++) + { + *(char *)(cromo_entrada + i) = *(char *)ap1; + ap1 = ap1 + 1; + } + + data_struct_ap1->fitness_entrada = htonl(*(int *)ap1); + ap1 = ap1 + 4; + data_struct_ap1->nivel_max = htonl(*(int *)ap1) & 0xFFFF; + data_struct_ap1->en_cromo_entrada = htonl(*(int *)ap1) >> 16; //han enviado un cromosoma? + ap1 = ap1 + 4; + data_struct_ap1->aux = htonl(*(int *)ap1); +/* printf("\nnivel_max:%0x-- ", data_struct_ap1->nivel_max);*/ + data_struct_ap1->maxgen = maxgeneraciones; + + cromo_sal1 = malloc(sizeof(cromo_sal1) * RESULTADOS * LONG_INDIV); if(cromo_sal1==0) printf("Error en malloc"); /* reservar para cromosomas */ + fitness1 = malloc(sizeof(fitness1) * RESULTADOS); if(fitness1==0) printf("Error en malloc"); + cromo_sal2 = malloc(sizeof(cromo_sal2) * RESULTADOS * LONG_INDIV); if(cromo_sal2==0) printf("Error en malloc"); + fitness2 = malloc(sizeof(fitness2) * RESULTADOS); if(fitness2==0) printf("Error en malloc"); + generacion = malloc(sizeof(generacion)); if(generacion==0) printf("Error en malloc"); + tiempo = malloc(sizeof(tiempo)* RESULTADOS ); if(tiempo==0) printf("Error en malloc"); + aux_sal = malloc(sizeof(aux_sal)* maxgeneraciones * 2 ); if(aux_sal==0) printf("Error en malloc"); + + data_struct_ap1->generacion = generacion; + data_struct_ap1->cromo_sal = cromo_sal1; + data_struct_ap1->fitness = fitness1; + data_struct_ap1->fitness_entrada = 0; + data_struct_ap1->tiempo = tiempo; + data_struct_ap1->aux_sal = aux_sal; + + *generacion = 0; + + evolucionar(data_struct_ap1); // evolucionar + +/* for(i=0; i < RESULTADOS ;i++)*/ +/* {*/ +/* printf(" %i-- fit:%i \t",i , *(fitness1 + i));*/ +/* mostrar_indiv(cromo_sal1 + (i*LONG_INDIV), pentarboles, vars);*/ +/* }*/ + + ap1 = data_socket_tx_ap; /* devolver resultados */ + *(int *)ap1 = ntohl(LONG_INDIV); + ap1 = ap1 + 4; + + for(i=0; i < RESULTADOS ;i++) + { + for(j=0; j < LONG_INDIV ;j++) + { + *(char *)ap1 = *(cromo_sal1 + j + (LONG_INDIV * i)); + ap1 ++; + } + *(int *)ap1 = ntohl(((*generacion) << 16) | (*(fitness1 + i))); + ap1 = ap1 + 4; + *(int *)ap1 = ntohl(*tiempo); + ap1 = ap1 + 4; + } + for(i=0; i < maxgeneraciones*2 ;i++) //devolver mediciones + { + *(int *)ap1 = ntohl(*(aux_sal+i)); + ap1 = ap1 + 4; + } + numbytes = ap1 - data_socket_tx_ap; + send(fd2, data_socket_tx_ap, numbytes, 0); /* devuelve cromosoma y fitness al cliente */ +/* printf("\n");*/ + + close(fd2); + free(cromo_entrada); + free(cromo_sal1); + free(fitness1); + free(cromo_sal2); + free(fitness2); + free(generacion); + free(tiempo); + free(aux_sal); + } + + +if(HW_ENABLE == 1){ + close_peripheral(evalfit_ptr1); + close_peripheral(evalfit_ptr2); + close_peripheral(evalfit_ptr3); + close_peripheral(evalfit_ptr4); +} +close(basemem); + + +free(funlut_ap); +free(puertas_ap); +free(data_socket_rx_ap); +free(data_socket_tx_ap); +shutdown(fd, SHUT_RDWR); +close(fd); + +return 0; +} diff --git a/Examples/ehw4/src/sintesishw_server.h b/Examples/ehw4/src/sintesishw_server.h new file mode 100644 index 0000000..6a6cb34 --- /dev/null +++ b/Examples/ehw4/src/sintesishw_server.h @@ -0,0 +1,58 @@ + +/** Genetic definitions **/ +#define HW_ENABLE 1 //cambiar en genetic.h habilitar hw, 0 se hace por SW + +#define RESULTADOS 2 + +#define ARBOLES 5 +#define LONG_ARBOL 8 + +#define nivel1 pentarboles * 4 +#define ARBOLES_INDIV (int)(nivel1 + *(nivel2+pentarboles) + *(nivel3+pentarboles) + *(nivel4+pentarboles) + *(nivel5+pentarboles)) +#define LONG_INDIV (int)(ARBOLES_INDIV * LONG_ARBOL) + +#define EVALFIT_PHYSBASE1 0xcd800000 +#define EVALFIT_PHYSBASE2 0xcd820000 +#define EVALFIT_PHYSBASE3 0xcd840000 +#define EVALFIT_PHYSBASE4 0xcd860000 + +//sockets defs +#define PORT 3550 /* El puerto que sera abierto */ +#define BACKLOG 2 /* El numero de conexiones permitidas */ +#define MAXDATASIZE 10000 /* El numero maximo de datos en bytes */ + +/* Variables globales */ +char *funlut_ap, *puertas_ap; +void *evalfit_ptr1, *evalfit_ptr4, *evalfit_ptr3, *evalfit_ptr2; +int maxgeneraciones, poblacion; + + +typedef long long timestamp_t; +static timestamp_t + get_timestamp () +{ + struct timeval now; + gettimeofday (&now, NULL); + return now.tv_usec + (timestamp_t)now.tv_sec *1000000 ; +} + +struct gen_datos_tipo +{ + int *objetivo; + int tamaobj; + int pentarboles; + int vars; + int tamacrom; + int maxgen; + char *cromo_sal; + int *fitness; + char *cromo_entrada; + int fitness_entrada; + int nivel_max; + int en_cromo_entrada; + int *generacion; + int *tiempo; + int aux; + int *aux_sal; +}; + diff --git a/Examples/ehw4/src/test/Makefile b/Examples/ehw4/src/test/Makefile new file mode 100755 index 0000000..bd1087c --- /dev/null +++ b/Examples/ehw4/src/test/Makefile @@ -0,0 +1,29 @@ +#OBJS := start.o main.o jz_serial.o + +CROSS := mipsel-openwrt-linux- +INCLUDE = -I. -lm +CCFLAGS = ${INCLUDE} ${DEBUG} ${WARNINGS} +#CFLAGS := -O2 -G 0 -mno-abicalls -fno-pic -mips32 -Iinclude +AFLAGS = -D__ASSEMBLY__ $(CFLAGS) +LDFLAGS := -T ld.script -nostdlib -EL +COMMON_SOURCES = jz47xx_gpio.c jz47xx_mmap.c +COMMON_OBJECTS = $(COMMON_SOURCES:.c=.o) +H_SOURCES = jz47xx_gpio.h jz47xx_mmap.h + +NANO_IP = 192.168.254.101 + +all: xburst + +xburst: xburst.c xburst.h $(COMMON_OBJECTS) + $(CROSS)gcc $(COMMON_OBJECTS) xburst.c -o xburst ${CCFLAGS} + +.c.o: + $(CROSS)gcc $(CCFLAGS) -c $< -o $@ +.S.o: + $(CROSS)gcc $(AFLAGS) -c $< -o $@ + +indent: + indent -bad -bap -nbc -bl -nce -i2 --no-tabs --line-length120 $(COMMON_SOURCES) $(H_SOURCES) + +upload: xburst + scp xburst root@$(NANO_IP):binaries diff --git a/Examples/ehw4/src/test/enable_irq.c b/Examples/ehw4/src/test/enable_irq.c new file mode 100755 index 0000000..ffb3653 --- /dev/null +++ b/Examples/ehw4/src/test/enable_irq.c @@ -0,0 +1,40 @@ +/* + JZ47xx test gpio + + Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com + Carlos Camargo cicamargoba@unal.edu.co + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include + +#include "jz47xx_gpio.h" + +#define IRQ_PORT JZ_GPIO_PORT_C +#define IRQ_PIN 15 + +int +main () +{ + JZ_PIO *pio = jz_gpio_map (IRQ_PORT); + + if (!pio) + return -1; + + jz_gpio_as_irq (pio, IRQ_PIN); + + return 0; +} diff --git a/Examples/ehw4/src/test/enable_rx.c b/Examples/ehw4/src/test/enable_rx.c new file mode 100755 index 0000000..be2775e --- /dev/null +++ b/Examples/ehw4/src/test/enable_rx.c @@ -0,0 +1,40 @@ +/* + JZ47xx test gpio + + Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com + Carlos Camargo cicamargoba@unal.edu.co + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include + +#include "jz47xx_gpio.h" + +#define RXD_PORT JZ_GPIO_PORT_D +#define RXD_PIN 26 + +int +main () +{ + JZ_PIO *pio = jz_gpio_map (RXD_PORT); + + if (!pio) + return -1; + + jz_gpio_as_func (pio, RXD_PIN, 1); + + return 0; +} diff --git a/Examples/ehw4/src/test/jz47xx_gpio.c b/Examples/ehw4/src/test/jz47xx_gpio.c new file mode 100755 index 0000000..7100647 --- /dev/null +++ b/Examples/ehw4/src/test/jz47xx_gpio.c @@ -0,0 +1,119 @@ +/* + JZ47xx GPIO at userspace + + Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include +#include + +#include +#include + + +#define JZ_GPIO_BASE 0x10010000 + +void +jz_gpio_as_output (JZ_PIO * pio, unsigned int o) +{ + pio->PXFUNC = (1 << (o)); + pio->PXSELC = (1 << (o)); + pio->PXDIRS = (1 << (o)); +} + +void +jz_gpio_as_input (JZ_PIO * pio, unsigned int o) +{ + pio->PXFUNC = (1 << (o)); + pio->PXSELC = (1 << (o)); + pio->PXDIRC = (1 << (o)); +} + +void +jz_gpio_as_irq (JZ_PIO * pio, unsigned int o) +{ + pio->PXFUNC = (1 << (o)); + pio->PXSELS = (1 << (o)); + pio->PXDIRC = (1 << (o)); +} + +void +jz_gpio_set_pin (JZ_PIO * pio, unsigned int o) +{ + pio->PXDATS = (1 << (o)); +} + +void +jz_gpio_clear_pin (JZ_PIO * pio, unsigned int o) +{ + pio->PXDATC = (1 << (o)); +} + +void +jz_gpio_out (JZ_PIO * pio, unsigned int o, unsigned int val) +{ + if (val == 0) + pio->PXDATC = (1 << (o)); + else + pio->PXDATS = (1 << (o)); +} + +unsigned int +jz_gpio_get_pin (JZ_PIO * pio, unsigned int o) +{ + return (pio->PXPIN & (1 << o)) ? 1 : 0; +} + +int +jz_gpio_as_func (JZ_PIO * pio, unsigned int o, int func) +{ + switch (func) + { + case 0: + pio->PXFUNS = (1 << o); + pio->PXTRGC = (1 << o); + pio->PXSELC = (1 << o); + pio->PXPES = (1 << o); + return 1; + + case 1: + pio->PXFUNS = (1 << o); + pio->PXTRGC = (1 << o); + pio->PXSELS = (1 << o); + pio->PXPES = (1 << o); + return 1; + + case 2: + pio->PXFUNS = (1 << o); + pio->PXTRGS = (1 << o); + pio->PXSELC = (1 << o); + pio->PXPES = (1 << o); + return 1; + } + return 0; +} + +JZ_PIO * +jz_gpio_map (int port) +{ + JZ_PIO *pio; + + pio = (JZ_PIO *) jz_mmap (JZ_GPIO_BASE); + pio = (JZ_PIO *) ((unsigned int) pio + port * 0x100); + + return pio; +} diff --git a/Examples/ehw4/src/test/jz47xx_gpio.h b/Examples/ehw4/src/test/jz47xx_gpio.h new file mode 100755 index 0000000..d8b0113 --- /dev/null +++ b/Examples/ehw4/src/test/jz47xx_gpio.h @@ -0,0 +1,84 @@ +/* + JZ47xx GPIO at userspace + + Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef __jz47xx_gpio_h__ +#define __jz47xx_gpio_h__ + +#define JZ_GPIO_PORT_A 0 +#define JZ_GPIO_PORT_B 1 +#define JZ_GPIO_PORT_C 2 +#define JZ_GPIO_PORT_D 3 + +typedef volatile unsigned int JZ_REG; /* Hardware register definition */ + +typedef struct _JZ_PIO +{ + JZ_REG PXPIN; /* PIN Level Register */ + JZ_REG Reserved0; + JZ_REG Reserved1; + JZ_REG Reserved2; + JZ_REG PXDAT; /* Port Data Register */ + JZ_REG PXDATS; /* Port Data Set Register */ + JZ_REG PXDATC; /* Port Data Clear Register */ + JZ_REG Reserved3; + JZ_REG PXIM; /* Interrupt Mask Register */ + JZ_REG PXIMS; /* Interrupt Mask Set Reg */ + JZ_REG PXIMC; /* Interrupt Mask Clear Reg */ + JZ_REG Reserved4; + JZ_REG PXPE; /* Pull Enable Register */ + JZ_REG PXPES; /* Pull Enable Set Reg. */ + JZ_REG PXPEC; /* Pull Enable Clear Reg. */ + JZ_REG Reserved5; + JZ_REG PXFUN; /* Function Register */ + JZ_REG PXFUNS; /* Function Set Register */ + JZ_REG PXFUNC; /* Function Clear Register */ + JZ_REG Reserved6; + JZ_REG PXSEL; /* Select Register */ + JZ_REG PXSELS; /* Select Set Register */ + JZ_REG PXSELC; /* Select Clear Register */ + JZ_REG Reserved7; + JZ_REG PXDIR; /* Direction Register */ + JZ_REG PXDIRS; /* Direction Set Register */ + JZ_REG PXDIRC; /* Direction Clear Register */ + JZ_REG Reserved8; + JZ_REG PXTRG; /* Trigger Register */ + JZ_REG PXTRGS; /* Trigger Set Register */ + JZ_REG PXTRGC; /* Trigger Set Register */ + JZ_REG Reserved9; + JZ_REG PXFLG; /* Port Flag Register */ + JZ_REG PXFLGC; /* Port Flag clear Register */ +} JZ_PIO, *PJZ_PIO; + +void jz_gpio_as_output (JZ_PIO * pio, unsigned int o); + +void jz_gpio_as_input (JZ_PIO * pio, unsigned int o); + +void jz_gpio_set_pin (JZ_PIO * pio, unsigned int o); + +void jz_gpio_clear_pin (JZ_PIO * pio, unsigned int o); + +void jz_gpio_out (JZ_PIO * pio, unsigned int o, unsigned int val); + +unsigned int jz_gpio_get_pin (JZ_PIO * pio, unsigned int o); + +int jz_gpio_as_func (JZ_PIO * pio, unsigned int o, int func); + +JZ_PIO *jz_gpio_map (int port); + +#endif diff --git a/Examples/ehw4/src/test/jz47xx_gpio.o b/Examples/ehw4/src/test/jz47xx_gpio.o new file mode 100755 index 0000000000000000000000000000000000000000..e79ca8c3a05a37e52b11254d24ea6a1188ef0c4f GIT binary patch literal 2984 zcmds3&1(};5TDJaT5GLq%^{%Z1}atyi?jtlP)KcSdk|5mpr>}zrfEv^VX}c(goj~?qm=%EmQzsWd z(xg?kHIc5vA}xkUzYFM=4mqlzF5j%KoDa(Ta%5vkZ~o=J}pkiBMT1M}PN&98y^4Pk!6s3Gjt z5R}!jJIk19?(?F=a2rGdoNv!I?Ad^IF}7ECXxBYZ=Q4!48~KV&e7qx#p6iEC6TM4h zt=!E^3~Ge^-Ta)@Mloyo1IWMnNBNy5Irdw>NTrPZl-PIlxMcX=9qZ`(Y59OY*WO(w zdaoJ5>o~S{o*jBsHobmICuRrlG1b3_G3ffKGdALs5T|7N;xh*6iO9Mu?EMqns#dGY z#ipIXI;#vK|COH?XIFg{fBmN4KQcIY&FmhzbN_^@=r_ zNu}axJcA^b?Krt)tl-4+NcM}wzVX|6$iqj$%@$7qb6*_br?8G}o8<~Vsol^ycziyH z#aTG#>F&o4@`NuI)Ox%g$i)8)cL^BmEgJwQFI4TiO)v1Y~t4 zw7&x`Nx>t9BUfia*BFY5!gvgF8y4$eeAeoZw+QEJ*c7RFN>|)(56ZXteWzcq@3w~4 zcVwVnowo9`)7zxW&Y{rj(^tdjJ37R8ZNiI0!n+CQt4YL@mEH?|)8`+6?4XDtaN_TQ zFZ=XK=v&a$^K48J2g+F>egV7!eG?e!CFsj2Yr^xt0$1erady7{aD`9hqq;vIcgC~HbX}jEi`%&!76hz&6T8sJH(f|?=TF&LVpHT2 zMLj{RMGORa2=%zS$G?!DtW_1joR|;;xF1n+T#yNJ4A@ih4v{5tG^Rq1Ls%#00OQO8 HxCB1{M5Wth literal 0 HcmV?d00001 diff --git a/Examples/ehw4/src/test/jz47xx_mmap.c b/Examples/ehw4/src/test/jz47xx_mmap.c new file mode 100755 index 0000000..93f70fa --- /dev/null +++ b/Examples/ehw4/src/test/jz47xx_mmap.c @@ -0,0 +1,64 @@ +/* + * JZ47xx GPIO lines + * + * Written 2010 by Andres Calderon andres.calderon@emqbit.com + */ + +#include +#include +#include +#include +#include +#include + +#include + + +void * +jz_mmap (off_t address) +{ + int fd; + + void *pio; + + if ((fd = open ("/dev/mem", O_RDWR | O_SYNC)) == -1) + { + fprintf (stderr, "Cannot open /dev/mem.\n"); + return 0; + } + + pio = (void *) mmap (0, getpagesize (), PROT_READ | PROT_WRITE, MAP_SHARED, fd, address); + + if (pio == (void *) -1) + { + fprintf (stderr, "Cannot mmap.\n"); + return 0; + } + + return pio; +} + +void * +jz_fpga_map (off_t address) +{ + int fd; + + void *fpga; + + if ((fd = open ("/dev/mem", O_RDWR | O_SYNC)) == -1) + { + fprintf (stderr, "Cannot open /dev/mem.\n"); + return 0; + } + + fpga = (void *) mmap (0, FPGA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, address); + + if (fpga == (void *) -1) + { + fprintf (stderr, "Cannot mmap.\n"); + return 0; + } + + return fpga; +} + diff --git a/Examples/ehw4/src/test/jz47xx_mmap.h b/Examples/ehw4/src/test/jz47xx_mmap.h new file mode 100755 index 0000000..dbb4821 --- /dev/null +++ b/Examples/ehw4/src/test/jz47xx_mmap.h @@ -0,0 +1,17 @@ +/* + * JZ47xx GPIO lines + * + * Written 2010 by Andres Calderon andres.calderon@emqbit.com + */ + +#ifndef __jz47xx_mmap_h__ +#define __jz47xx_mmap_h__ + +#include + +#define FPGA_SIZE (1 << 15) + +void *jz_mmap (off_t address); +void *jz_fpga_map (off_t address); + +#endif diff --git a/Examples/ehw4/src/test/jz47xx_mmap.o b/Examples/ehw4/src/test/jz47xx_mmap.o new file mode 100755 index 0000000000000000000000000000000000000000..366086d641ca74e5e17fb0892c9d4928f9b51c21 GIT binary patch literal 2156 zcmcgtzfTik7=GJp0Tl!rq9hW%Y7JG%L8S4wrV5IKF$|b6kieB5wT5f!_0Y;9e}G9B z{{Z6T*406@Q3eJFMn?t*2L>J7OzQJo?<)t1;9z`{>+?SE&+q-d`>rqU+`k(Ng+xh6 zI%J!PywXIXJt8SDASvC_sX{&6Xsiwl%77zkk;r{ZYf~siPL2YW!PW!|YYeULBUzfezWk zZi)PlJz4hmWUqaYc(~Yr3WwnQ~bS$I9gk^F=BPMk(uvVP~z(V$Lu#`H>4S z7n{LzMccLt$VD^5bX_N(S#+)P&gJdJxKF&RZGKQ1sE2(5z_s<{IDQZKI$;unbs(_| zI`boVc)`y2+A7FZm5T!Ea6lacS6;FphEs zPjHTDEP^v~4(@@P<2LkQy|<_r6y=-n##QjEvq1A^~TfYHD6W@?y_7m?D7g~qU+V@>M) za_;_J{PZqd`0tSe`JP2^xLG0& zeu0QhSRrEIcR=RXfy`ecN8UO)@C%UnUx~<1VkG(pf%K<bxPM{~C~a>p}^Z)<= literal 0 HcmV?d00001 diff --git a/Examples/ehw4/src/test/jz_init_sram.c b/Examples/ehw4/src/test/jz_init_sram.c new file mode 100755 index 0000000..d8e1494 --- /dev/null +++ b/Examples/ehw4/src/test/jz_init_sram.c @@ -0,0 +1,75 @@ +/* SAKC FPGA/SRAM interface test + +Copyright (C) 2010 Carlos Camargo cicamargoba@unal.edu.co + Andres Calderon andres.calderon@emqbit.com + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include +#include + +#include "jz47xx_gpio.h" +#include "jz47xx_mmap.h" + +#define CS2_PORT JZ_GPIO_PORT_B +#define CS2_PIN 26 + +int +main () +{ + int i; + JZ_PIO *pio; + int *virt_addr; + + pio = jz_gpio_map (CS2_PORT); + jz_gpio_as_func (pio, CS2_PIN, 0); + + virt_addr = (int *) jz_mmap (0x13010000) + 0x18/sizeof(int); + + if (*virt_addr != 0xFFF7700) + { // 0 WS, 8 bits + *virt_addr = 0xFFF7700; + printf ("Configuring CS2 8 bits \n"); + } + else + printf ("CS3, already configured\n"); + + virt_addr = (int *) jz_fpga_map (0x15000000); + + printf ("Writing Memory..\n"); + + srand48(0x3c); + + for (i = 0; i < FPGA_SIZE/4; i++) + virt_addr[i] = (lrand48() & 0x00ff); + + printf ("Reading Memory..\n"); + + + srand48(0x3c); + + for (i = 0; i < FPGA_SIZE/4; i++){ + printf("%X\n", virt_addr[i]); + if (virt_addr[i] != (lrand48() & 0x00ff)){ + printf ("FPGA - Xburst connection test failed on Address:0x%x\n", i); + return 1; /* Error */ + } + } + printf ("%d\n", i); + printf ("FPGA - Xburst connection test passed\n"); + + return 0; +} diff --git a/Examples/ehw4/src/test/jz_test_gpio.c b/Examples/ehw4/src/test/jz_test_gpio.c new file mode 100755 index 0000000..ea330f2 --- /dev/null +++ b/Examples/ehw4/src/test/jz_test_gpio.c @@ -0,0 +1,59 @@ +/* + JZ47xx test gpio + + Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com + Carlos Camargo cicamargoba@unal.edu.co + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include + +#include "jz47xx_gpio.h" + +//#define TEST_PORT JZ_GPIO_PORT_C +//#define TEST_PIN 17 + +int +main (int argc,char *argv[]) + +{ + int TEST_PORT, TEST_PIN; + + if(argc != 3){ + fprintf(stderr,"\nUsage: %s TEST_PIN_PORT(A=0, B=1, C=2, D=3) TEST_PIN \n",argv[0]); + } + + TEST_PORT = JZ_GPIO_PORT_C; + TEST_PIN = 17; + JZ_PIO *pio = jz_gpio_map (TEST_PORT); + + if (!pio) + return -1; + + jz_gpio_as_output (pio, TEST_PIN); + + int tg = 1; + + while (1) + { + jz_gpio_out (pio, TEST_PIN, tg); + printf ("[%d]", jz_gpio_get_pin (pio, TEST_PIN)); + fflush (stdout); + usleep (500 * 1000); + tg = !tg; + } + return 0; +} diff --git a/Examples/ehw4/src/test/xburst b/Examples/ehw4/src/test/xburst new file mode 100755 index 0000000000000000000000000000000000000000..dafbed86c9709fcc0c89d7ec9764904fbbe63016 GIT binary patch literal 57710 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 D5&n){ literal 0 HcmV?d00001 diff --git a/Examples/ehw4/src/test/xburst.c b/Examples/ehw4/src/test/xburst.c new file mode 100755 index 0000000..20a3376 --- /dev/null +++ b/Examples/ehw4/src/test/xburst.c @@ -0,0 +1,70 @@ +#include +#include +#include "fcntl.h" +#include +#include +#include "jz47xx_gpio.h" +#include + +#define CS2_PORT JZ_GPIO_PORT_B +#define CS2_PIN 26 + +int periph_map(off_t offset) +{ +int basemem, baseperiph; + basemem = open("/dev/mem", (O_RDWR | O_SYNC)); //abrir dispositivo memoria para mapear dir del periferico + if(basemem == -1) + { + printf("Error to open /dev/mem \n"); + return -1; + } + baseperiph = (int )mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, basemem, offset);// & ~MAP_MASK); + if (baseperiph == -1) + { + printf ("Cannot mmap.\n"); + return -1; + } +return baseperiph; +} + + +int main(){ +int i, j; +int basemem, base_periferico, *ConfigRegsBase_ptr; +void *peripheral1_ptr; +void *pio; + +printf("Xburst Test..."); + +basemem = open("/dev/mem", (O_RDWR | O_SYNC)); //abrir dispositivo memoria para mapear dir del periferico +if(basemem == -1) +{ + printf("Error al abrir /dev/mem \n"); + return -1; +} + +pio = jz_gpio_map(CS2_PORT); +jz_gpio_as_func (pio, CS2_PIN, 0); + +ConfigRegsBase_ptr = (int *)periph_map(CONFIG_REGS_BASE);// + SACR2_OFFSET/sizeof(int);//SMCR2_OFFSET/sizeof(int); +printf("\n%0x ", *(ConfigRegsBase_ptr + SMCR2_OFFSET/sizeof(int))); +munmap(ConfigRegsBase_ptr, MAP_SIZE); + +peripheral1_ptr = (int *)periph_map(0x14000000); + +for(i = 0; i < 0xfff; i=i+4){ + j = rand(); +// *(int *)(peripheral1_ptr + i) = j; +// if(j != *(int *)(peripheral1_ptr + i)){ +// printf("\nError at %0x offset:%i\n", (int *)(peripheral1_ptr + i), i); exit(0); +// } + printf("\nReg %i: write:%0x read:%0x", i, j, *(int *)(peripheral1_ptr + i) ); +} +printf("\nPassed Test\n"); +munmap(peripheral1_ptr, MAP_SIZE); + +//munmap(base_periferico, MAP_SIZE); +close(basemem); +exit(0); +} + diff --git a/Examples/ehw4/src/test/xburst.h b/Examples/ehw4/src/test/xburst.h new file mode 100755 index 0000000..a701846 --- /dev/null +++ b/Examples/ehw4/src/test/xburst.h @@ -0,0 +1,10 @@ + +#define CONFIG_REGS_BASE 0x13010000 +#define SMCR2_OFFSET 0x18 +#define SACR2_OFFSET 0x38 + +#define MAP_SIZE 0x10000Ul +#define MAP_MASK (MAP_SIZE - 1) +#define XBURST_PHYSBASE1 0x14000000 + +//SMCR2 reset:0x0FFF7700 Address: 0x13010018 diff --git a/KICAD_design_files/SAKC_PCB_v2/SAKC.drl b/KICAD_design_files/SAKC_PCB_v2/SAKC.drl index b41e548..2cb99f5 100644 --- a/KICAD_design_files/SAKC_PCB_v2/SAKC.drl +++ b/KICAD_design_files/SAKC_PCB_v2/SAKC.drl @@ -1,467 +1,481 @@ M48 -;DRILL file {PCBnew (20090216-final)} date Fri 23 Apr 2010 01:13:58 PM COT -;FORMAT={-.-/ absolute / inch / decimal} +;DRILL file {PCBnew (20090216-final)} date Tue 28 Sep 2010 03:28:56 PM COT +;FORMAT={-.-/ absolute / metric / decimal} R,T VER,1 FMAT,2 -INCH,TZ +METRIC,TZ TCST,OFF ICI,OFF ATC,ON -T1C0.012 -T2C0.030 -T3C0.034 -T4C0.038 -T5C0.040 -T6C0.042 -T7C0.052 -T8C0.118 +T1C0.300 +T2C0.762 +T3C0.864 +T4C0.965 +T5C1.016 +T6C1.067 +T7C1.321 +T8C2.997 % M47 G05 -M72 +M71 T1 -X6.466Y5.799 -X6.496Y5.734 -X6.501Y6.072 -X6.501Y6.091 -X6.501Y6.112 -X6.502Y5.899 -X6.505Y6.206 -X6.515Y6.554 -X6.531Y5.500 -X6.532Y5.434 -X6.532Y5.467 -X6.537Y6.410 -X6.540Y6.137 -X6.548Y6.548 -X6.565Y6.109 -X6.568Y6.424 -X6.579Y6.778 -X6.592Y6.453 -X6.597Y6.138 -X6.607Y6.493 -X6.607Y5.997 -X6.634Y6.522 -X6.636Y6.984 -X6.641Y5.972 -X6.664Y5.202 -X6.665Y6.851 -X6.699Y4.806 -X6.708Y6.805 -X6.710Y4.771 -X6.712Y6.032 -X6.722Y5.762 -X6.733Y5.571 -X6.747Y5.159 -X6.747Y5.832 -X6.749Y5.641 -X6.784Y5.897 -X6.802Y7.076 -X6.803Y7.160 -X6.803Y7.120 -X6.816Y6.075 -X6.822Y6.130 -X6.833Y5.202 -X6.834Y5.889 -X6.837Y4.383 -X6.838Y4.598 -X6.847Y6.969 -X6.881Y5.477 -X6.888Y5.640 -X6.905Y5.392 -X6.907Y5.222 -X6.909Y5.355 -X6.912Y6.997 -X6.933Y5.767 -X6.936Y6.478 -X6.946Y5.592 -X6.955Y6.064 -X6.957Y6.284 -X6.958Y5.985 -X6.959Y6.759 -X6.962Y4.697 -X6.975Y6.254 -X6.984Y6.587 -X6.985Y6.310 -X6.991Y6.198 -X7.006Y4.628 -X7.012Y5.221 -X7.016Y5.714 -X7.019Y6.217 -X7.030Y5.385 -X7.030Y5.888 -X7.032Y5.618 -X7.044Y6.066 -X7.052Y4.641 -X7.052Y6.196 -X7.057Y5.914 -X7.065Y5.364 -X7.071Y5.855 -X7.078Y6.237 -X7.084Y4.601 -X7.103Y6.190 -X7.107Y5.485 -X7.110Y5.084 -X7.115Y5.997 -X7.122Y5.007 -X7.129Y6.255 -X7.139Y5.929 -X7.145Y5.081 -X7.147Y6.230 -X7.148Y5.430 -X7.150Y4.541 -X7.153Y6.891 -X7.172Y6.203 -X7.175Y6.920 -X7.176Y4.813 -X7.184Y4.486 -X7.191Y5.899 -X7.199Y7.225 -X7.202Y6.243 -X7.209Y5.844 -X7.218Y5.384 -X7.225Y5.708 -X7.226Y5.590 -X7.230Y7.232 -X7.231Y6.226 -X7.245Y4.866 -X7.246Y5.845 -X7.254Y6.527 -X7.257Y7.214 -X7.264Y6.222 -X7.264Y6.291 -X7.264Y6.497 -X7.278Y6.562 -X7.291Y6.462 -X7.291Y7.215 -X7.296Y6.593 -X7.298Y6.163 -X7.299Y5.877 -X7.325Y7.210 -X7.326Y5.728 -X7.329Y6.599 -X7.335Y6.284 -X7.336Y6.177 -X7.352Y6.687 -X7.355Y6.580 -X7.355Y7.228 -X7.356Y6.223 -X7.362Y5.858 -X7.379Y7.047 -X7.381Y6.195 -X7.385Y7.218 -X7.395Y7.080 -X7.405Y5.910 -X7.410Y5.549 -X7.416Y7.112 -X7.418Y6.218 -X7.425Y6.470 -X7.442Y5.672 -X7.443Y6.281 -X7.445Y6.529 -X7.446Y7.144 -X7.447Y5.494 -X7.447Y6.574 -X7.451Y7.325 -X7.453Y5.050 -X7.453Y6.623 -X7.459Y6.663 -X7.460Y6.461 -X7.484Y5.811 -X7.486Y6.599 -X7.499Y7.016 -X7.514Y6.757 -X7.514Y6.863 -X7.515Y6.506 -X7.526Y6.543 -X7.537Y5.479 -X7.542Y5.197 -X7.545Y6.739 -X7.576Y6.752 -X7.582Y4.826 -X7.602Y5.361 -X7.603Y5.722 -X7.606Y6.663 -X7.606Y7.026 -X7.608Y7.336 -X7.610Y5.839 -X7.640Y6.757 -X7.655Y5.106 -X7.672Y6.776 -X7.681Y5.271 -X7.682Y5.326 -X7.699Y6.622 -X7.703Y6.863 -X7.704Y6.695 -X7.708Y6.579 -X7.720Y5.280 -X7.725Y5.824 -X7.726Y4.486 -X7.734Y6.768 -X7.760Y4.431 -X7.762Y4.817 -X7.763Y4.922 -X7.766Y6.763 -X7.770Y5.294 -X7.797Y7.329 -X7.814Y5.144 -X7.829Y6.768 -X7.860Y7.326 -X7.917Y5.134 -X7.931Y5.202 -X7.973Y6.424 -X7.985Y6.391 -X8.006Y5.766 -X8.013Y6.691 -X8.015Y5.887 -X8.031Y6.401 -X8.043Y4.933 -X8.045Y4.817 -X8.065Y5.771 -X8.068Y5.909 -X8.075Y6.412 -X8.093Y5.885 -X8.096Y5.770 -X8.103Y6.569 -X8.117Y4.824 -X8.121Y6.014 -X8.133Y6.162 -X8.137Y5.315 -X8.138Y6.111 -X8.138Y4.934 -X8.138Y6.267 -X8.139Y6.063 -X8.141Y5.937 -X8.146Y6.212 -X8.149Y5.767 -X8.150Y5.989 -X8.158Y6.038 -X8.160Y4.996 -X8.164Y6.135 -X8.164Y6.088 -X8.165Y5.087 -X8.173Y5.910 -X8.174Y6.187 -X8.175Y6.237 -X8.179Y5.965 -X8.183Y6.422 -X8.213Y5.794 -X8.217Y5.826 -X8.226Y6.570 -X8.238Y5.169 -X8.247Y5.230 -X8.264Y6.419 -X8.274Y5.816 -X8.276Y4.914 -X8.298Y6.409 -X8.303Y5.564 -X8.310Y4.888 -X8.322Y6.355 -X8.330Y5.230 -X8.337Y6.412 -X8.341Y4.928 -X8.348Y6.333 -X8.349Y5.126 -X8.377Y5.007 -X8.389Y5.409 -X8.413Y7.076 -X8.429Y5.353 -X8.439Y4.786 -X8.443Y5.684 -X8.444Y6.560 -X8.445Y5.490 -X8.454Y7.038 -X8.461Y4.937 -X8.476Y5.268 -X8.500Y5.335 -X8.505Y5.548 -X8.517Y6.821 -X8.517Y5.213 -X8.543Y6.166 -X8.548Y5.945 -X8.550Y5.910 -X8.552Y5.269 -X8.558Y7.066 -X8.564Y6.069 -X8.569Y6.206 -X8.598Y5.562 -X8.607Y5.700 -X8.609Y5.833 -X8.638Y6.266 -X8.643Y6.084 -X8.657Y5.696 -X8.663Y6.438 -X8.664Y5.634 -X8.677Y5.385 -X8.688Y6.720 -X8.709Y6.296 -X8.717Y5.425 -X8.726Y6.697 -X8.756Y5.848 -X8.765Y6.316 -X8.776Y6.676 -X8.779Y6.744 -X8.787Y6.440 -X8.813Y6.142 -X8.814Y6.914 -X8.821Y5.183 -X8.834Y6.969 -X8.850Y7.066 -X8.852Y5.233 -X8.853Y5.134 -X8.855Y5.849 -X8.867Y7.026 -X8.882Y6.075 -X8.884Y5.184 -X8.884Y7.067 -X8.885Y6.302 -X8.887Y5.311 -X8.897Y6.896 -X8.902Y7.026 -X8.905Y5.572 -X8.914Y5.813 -X8.918Y6.566 -X8.919Y7.067 -X8.933Y6.189 -X8.943Y5.909 -X8.963Y5.560 -X8.970Y6.426 -X8.975Y5.963 -X8.976Y6.317 -X8.977Y6.563 -X8.990Y6.179 -X8.994Y5.826 -X9.004Y6.107 -X9.006Y6.266 -X9.022Y5.998 -X9.027Y6.434 -X9.037Y6.574 -X9.048Y6.914 -X9.070Y7.042 -X9.071Y6.363 -X9.073Y6.987 -X9.090Y5.246 -X9.099Y6.572 -X9.115Y4.942 -X9.128Y7.051 -X9.129Y6.993 -X9.130Y6.341 -X9.136Y4.528 -X9.137Y6.241 -X9.139Y5.981 -X9.149Y4.890 -X9.149Y4.992 -X9.150Y5.809 -X9.153Y6.524 -X9.168Y6.095 -X9.176Y5.051 -X9.179Y6.990 -X9.179Y7.048 -X9.180Y4.942 -X9.187Y5.278 -X9.228Y6.991 -X9.228Y7.049 -X9.234Y5.090 -X9.239Y4.698 -X9.246Y6.127 -X9.270Y5.977 -X9.270Y5.920 -X9.286Y6.277 -X9.322Y5.230 -X9.323Y5.230 -X9.361Y5.048 -X9.362Y5.227 -X9.406Y5.230 +X155.499Y-157.300 +X158.399Y-139.400 +X158.801Y-137.399 +X158.999Y-143.401 +X159.499Y-146.101 +X160.299Y-169.700 +X160.500Y-168.100 +X160.701Y-151.900 +X160.800Y-150.701 +X162.799Y-143.401 +X163.200Y-152.799 +X163.401Y-153.700 +X163.627Y-148.488 +X163.800Y-152.199 +X163.800Y-162.001 +X163.901Y-163.299 +X164.000Y-164.701 +X164.000Y-166.101 +X164.099Y-168.900 +X164.201Y-143.401 +X164.399Y-151.300 +X164.399Y-162.601 +X164.399Y-164.000 +X164.501Y-160.299 +X164.600Y-165.499 +X164.600Y-166.700 +X165.001Y-144.899 +X165.100Y-167.401 +X165.400Y-159.400 +X167.112Y-175.750 +X167.401Y-129.499 +X167.401Y-147.300 +X168.554Y-180.993 +X168.699Y-134.501 +X168.999Y-166.901 +X169.266Y-132.121 +X169.291Y-177.615 +X169.400Y-120.000 +X169.400Y-163.700 +X169.400Y-164.501 +X169.601Y-154.701 +X169.601Y-166.299 +X169.863Y-151.399 +X169.901Y-144.800 +X170.000Y-142.499 +X170.000Y-163.101 +X170.000Y-167.000 +X170.101Y-164.099 +X170.101Y-164.899 +X170.139Y-141.564 +X170.200Y-120.401 +X170.383Y-176.446 +X170.401Y-165.699 +X170.729Y-146.365 +X171.023Y-141.508 +X171.099Y-129.499 +X171.425Y-143.281 +X172.601Y-131.300 +X172.799Y-184.201 +X173.553Y-132.121 +X173.594Y-149.576 +X173.660Y-111.323 +X173.690Y-116.799 +X173.914Y-180.612 +X174.772Y-139.121 +X174.955Y-143.256 +X175.387Y-136.957 +X175.443Y-132.629 +X175.484Y-136.022 +X175.565Y-181.323 +X176.111Y-146.472 +X176.174Y-164.536 +X176.439Y-142.047 +X176.713Y-159.614 +X176.743Y-152.019 +X176.835Y-119.304 +X177.170Y-158.841 +X177.383Y-167.315 +X177.414Y-160.284 +X177.576Y-157.439 +X177.942Y-117.551 +X178.097Y-132.621 +X178.201Y-145.128 +X178.283Y-157.922 +X178.562Y-136.779 +X178.562Y-149.555 +X178.613Y-142.697 +X178.918Y-154.076 +X179.121Y-117.881 +X179.121Y-157.368 +X179.243Y-150.205 +X179.446Y-136.246 +X179.608Y-148.722 +X179.791Y-158.415 +X179.934Y-116.865 +X180.421Y-157.216 +X180.518Y-139.319 +X180.594Y-129.134 +X180.721Y-152.324 +X180.899Y-127.178 +X181.072Y-158.882 +X181.336Y-150.592 +X181.483Y-129.057 +X181.539Y-158.232 +X181.564Y-137.919 +X181.610Y-115.341 +X181.681Y-175.026 +X182.169Y-157.551 +X182.245Y-175.768 +X182.270Y-122.245 +X182.474Y-113.944 +X182.659Y-149.824 +X182.855Y-183.510 +X182.941Y-158.577 +X183.119Y-148.448 +X183.337Y-136.754 +X183.505Y-144.978 +X183.530Y-141.996 +X183.642Y-183.693 +X183.672Y-158.151 +X184.018Y-123.586 +X184.059Y-148.468 +X184.252Y-165.786 +X184.318Y-183.223 +X184.506Y-158.029 +X184.506Y-159.791 +X184.516Y-165.029 +X184.861Y-166.675 +X185.186Y-164.145 +X185.196Y-183.266 +X185.318Y-167.462 +X185.379Y-156.535 +X185.395Y-149.276 +X186.050Y-183.144 +X186.080Y-145.491 +X186.162Y-167.615 +X186.309Y-159.614 +X186.345Y-156.891 +X186.741Y-169.850 +X186.817Y-167.142 +X186.822Y-183.591 +X186.842Y-158.064 +X186.995Y-148.793 +X187.432Y-178.989 +X187.482Y-157.358 +X187.574Y-183.327 +X187.838Y-179.832 +X188.087Y-150.114 +X188.206Y-140.937 +X188.366Y-180.645 +X188.407Y-157.937 +X188.590Y-164.328 +X189.027Y-144.069 +X189.057Y-159.532 +X189.103Y-165.837 +X189.128Y-181.453 +X189.154Y-139.548 +X189.154Y-166.980 +X189.255Y-186.050 +X189.301Y-128.260 +X189.306Y-168.224 +X189.456Y-169.235 +X189.489Y-164.099 +X190.094Y-147.599 +X190.142Y-167.612 +X190.475Y-178.206 +X190.845Y-171.623 +X190.856Y-174.320 +X190.886Y-165.242 +X191.171Y-166.197 +X191.435Y-139.172 +X191.577Y-131.999 +X191.643Y-171.176 +X192.430Y-171.501 +X192.593Y-122.570 +X193.091Y-136.169 +X193.116Y-145.339 +X193.192Y-169.240 +X193.203Y-178.450 +X193.243Y-186.334 +X193.294Y-148.311 +X194.056Y-171.623 +X194.442Y-129.703 +X194.869Y-172.110 +X195.097Y-133.883 +X195.123Y-135.280 +X195.562Y-168.191 +X195.656Y-174.320 +X195.682Y-170.053 +X195.783Y-167.107 +X196.088Y-134.112 +X196.225Y-147.930 +X196.240Y-113.944 +X196.454Y-171.907 +X197.104Y-112.547 +X197.145Y-122.347 +X197.185Y-125.029 +X197.267Y-171.785 +X197.348Y-134.478 +X198.044Y-186.157 +X198.486Y-130.658 +X198.852Y-171.907 +X199.644Y-186.080 +X201.092Y-130.414 +X201.447Y-132.121 +X202.514Y-163.170 +X202.809Y-162.326 +X203.342Y-146.467 +X203.530Y-169.951 +X203.576Y-149.535 +X203.987Y-162.585 +X204.287Y-125.303 +X204.343Y-122.352 +X204.851Y-146.583 +X204.927Y-150.089 +X205.110Y-162.870 +X205.567Y-149.479 +X205.649Y-146.548 +X205.816Y-166.853 +X206.172Y-122.530 +X206.268Y-152.751 +X206.568Y-156.510 +X206.680Y-135.001 +X206.695Y-155.224 +X206.705Y-125.324 +X206.715Y-159.187 +X206.731Y-154.000 +X206.781Y-150.800 +X206.908Y-157.785 +X206.985Y-146.482 +X207.010Y-152.121 +X207.213Y-153.365 +X207.264Y-126.898 +X207.366Y-155.829 +X207.376Y-154.635 +X207.391Y-129.210 +X207.594Y-150.114 +X207.609Y-157.145 +X207.645Y-158.420 +X207.747Y-151.511 +X207.858Y-163.119 +X208.610Y-147.168 +X208.712Y-147.980 +X208.930Y-166.878 +X209.245Y-131.293 +X209.474Y-132.842 +X209.906Y-163.048 +X210.160Y-147.726 +X210.210Y-124.816 +X210.759Y-162.799 +X210.896Y-141.326 +X211.074Y-124.155 +X211.379Y-161.417 +X211.582Y-132.842 +X211.750Y-162.875 +X211.856Y-125.171 +X212.039Y-160.858 +X212.060Y-130.211 +X212.776Y-127.173 +X213.086Y-137.394 +X213.685Y-179.730 +X214.097Y-135.966 +X214.356Y-121.554 +X214.452Y-144.374 +X214.478Y-166.624 +X214.498Y-139.436 +X214.742Y-178.755 +X214.904Y-125.405 +X215.290Y-133.807 +X215.910Y-135.504 +X216.027Y-140.919 +X216.327Y-173.248 +X216.332Y-132.410 +X216.997Y-156.616 +X217.119Y-151.003 +X217.180Y-150.124 +X217.221Y-133.833 +X217.363Y-179.466 +X217.526Y-154.153 +X217.653Y-157.632 +X218.389Y-141.275 +X218.618Y-144.780 +X218.669Y-148.158 +X219.415Y-159.146 +X219.532Y-154.534 +X219.885Y-144.683 +X220.035Y-163.525 +X220.066Y-143.093 +X220.396Y-136.779 +X220.675Y-170.688 +X221.204Y-159.918 +X221.412Y-137.795 +X221.640Y-170.104 +X222.402Y-148.539 +X222.626Y-160.426 +X222.910Y-169.570 +X222.976Y-171.308 +X223.190Y-163.576 +X223.845Y-156.017 +X223.865Y-175.626 +X224.053Y-131.648 +X224.384Y-177.013 +X224.800Y-179.487 +X224.841Y-132.918 +X224.866Y-130.393 +X224.917Y-148.565 +X225.222Y-178.460 +X225.593Y-154.310 +X225.654Y-131.674 +X225.654Y-179.502 +X225.679Y-160.071 +X225.730Y-134.899 +X225.984Y-175.158 +X226.111Y-178.460 +X226.187Y-141.529 +X226.416Y-147.650 +X226.517Y-166.776 +X226.543Y-179.502 +X226.893Y-157.196 +X227.157Y-150.084 +X227.660Y-141.224 +X227.828Y-163.210 +X227.965Y-151.460 +X227.990Y-160.447 +X228.016Y-166.700 +X228.346Y-156.947 +X228.448Y-147.980 +X228.702Y-155.118 +X228.763Y-159.146 +X229.159Y-152.349 +X229.291Y-163.413 +X229.540Y-166.980 +X229.819Y-175.605 +X230.388Y-178.877 +X230.403Y-161.620 +X230.454Y-177.470 +X230.886Y-133.248 +X231.115Y-166.929 +X231.521Y-125.527 +X231.851Y-179.095 +X231.877Y-177.622 +X231.892Y-161.056 +X232.054Y-115.001 +X232.080Y-158.532 +X232.126Y-151.922 +X232.385Y-124.206 +X232.385Y-126.797 +X232.410Y-147.549 +X232.491Y-165.720 +X232.867Y-154.818 +X233.070Y-128.295 +X233.147Y-177.546 +X233.147Y-179.019 +X233.172Y-125.527 +X233.350Y-134.061 +X234.389Y-177.576 +X234.391Y-179.045 +X234.533Y-129.276 +X234.671Y-119.329 +X234.848Y-155.626 +X235.448Y-151.816 +X235.458Y-150.368 +X235.869Y-159.431 +X236.799Y-131.900 +X237.769Y-128.219 +X238.201Y-131.900 T2 -X6.608Y5.455 -X6.608Y5.533 -X6.608Y5.612 -X6.608Y5.691 -X6.686Y5.455 -X6.686Y5.533 -X6.686Y5.612 -X6.686Y5.691 +X155.499Y-136.500 +X155.499Y-138.481 +X155.499Y-140.487 +X155.499Y-142.494 +X157.480Y-136.500 +X157.480Y-138.481 +X157.480Y-140.487 +X157.480Y-142.494 T3 -X7.990Y4.448 -X7.991Y4.546 -X8.090Y4.448 -X8.091Y4.546 -X8.190Y4.450 -X8.191Y4.546 -X8.290Y4.448 -X8.291Y4.546 -X9.369Y5.307 -X9.369Y5.386 -X9.369Y5.464 -X9.369Y5.543 -X9.369Y5.622 -X9.369Y5.701 -X9.369Y5.779 -X9.369Y5.858 -X9.369Y5.937 -X9.369Y6.016 -X9.369Y6.094 -X9.369Y6.173 -X9.369Y6.252 -X9.369Y6.331 -X9.369Y6.409 -X9.369Y6.488 -X9.369Y6.567 -X9.369Y6.646 -X9.369Y6.724 -X9.369Y6.803 -X9.448Y5.307 -X9.448Y5.386 -X9.448Y5.464 -X9.448Y5.543 -X9.448Y5.622 -X9.448Y5.701 -X9.448Y5.779 -X9.448Y5.858 -X9.448Y5.937 -X9.448Y6.016 -X9.448Y6.094 -X9.448Y6.173 -X9.448Y6.252 -X9.448Y6.331 -X9.448Y6.409 -X9.448Y6.488 -X9.448Y6.567 -X9.448Y6.646 -X9.448Y6.724 -X9.448Y6.803 +X202.946Y-112.979 +X202.971Y-115.468 +X205.486Y-112.979 +X205.511Y-115.468 +X208.026Y-113.030 +X208.051Y-115.468 +X210.566Y-112.979 +X210.591Y-115.468 +X237.973Y-134.798 +X237.973Y-136.804 +X237.973Y-138.786 +X237.973Y-140.792 +X237.973Y-142.799 +X237.973Y-144.805 +X237.973Y-146.787 +X237.973Y-148.793 +X237.973Y-150.800 +X237.973Y-152.806 +X237.973Y-154.788 +X237.973Y-156.794 +X237.973Y-158.801 +X237.973Y-160.807 +X237.973Y-162.789 +X237.973Y-164.795 +X237.973Y-166.802 +X237.973Y-168.808 +X237.973Y-170.790 +X237.973Y-172.796 +X239.979Y-134.798 +X239.979Y-136.804 +X239.979Y-138.786 +X239.979Y-140.792 +X239.979Y-142.799 +X239.979Y-144.805 +X239.979Y-146.787 +X239.979Y-148.793 +X239.979Y-150.800 +X239.979Y-152.806 +X239.979Y-154.788 +X239.979Y-156.794 +X239.979Y-158.801 +X239.979Y-160.807 +X239.979Y-162.789 +X239.979Y-164.795 +X239.979Y-166.802 +X239.979Y-168.808 +X239.979Y-170.790 +X239.979Y-172.796 T4 -X7.335Y4.469 -X7.650Y4.469 +X186.309Y-113.513 +X194.310Y-113.513 T5 -X6.505Y4.921 -X6.505Y5.098 -X8.456Y7.385 -X8.633Y7.385 -X8.886Y7.394 -X9.063Y7.394 +X155.699Y-123.599 +X155.699Y-128.095 +X214.782Y-187.574 +X219.278Y-187.574 +X225.715Y-187.797 +X230.210Y-187.797 T6 -X6.496Y5.319 -X6.582Y4.553 -X6.596Y5.319 -X6.755Y4.553 -X8.405Y4.452 -X8.405Y4.552 +X155.499Y-133.701 +X158.039Y-133.701 +X167.183Y-115.646 +X171.577Y-115.646 +X213.487Y-113.081 +X213.487Y-115.621 T7 -X6.603Y4.871 -X6.603Y5.147 -X8.406Y7.287 -X8.682Y7.287 -X8.836Y7.296 -X9.112Y7.296 +X158.189Y-122.329 +X158.189Y-129.339 +X213.512Y-185.085 +X220.523Y-185.085 +X224.445Y-185.308 +X231.455Y-185.308 T8 -X6.589Y7.343 -X6.847Y4.987 -X8.567Y4.715 -X8.717Y4.565 -X8.717Y4.815 -X9.380Y4.494 -X9.381Y7.342 +X158.775Y-114.699 +X158.847Y-186.108 +X217.602Y-119.761 +X221.412Y-115.951 +X221.412Y-122.301 +X238.252Y-114.148 +X238.277Y-186.487 T0 M30 diff --git a/binaries/reflash/Makefile b/binaries/reflash/Makefile index 3c50f91..39718d9 100644 --- a/binaries/reflash/Makefile +++ b/binaries/reflash/Makefile @@ -2,11 +2,11 @@ # Written 2010, by Xiangfu Liu. # -LOADER=openwrt-xburst-qi_lb60-u-boot.bin -KERNEL=openwrt-xburst-qi_lb60-uImage.bin -ROOTFS_UBI=openwrt-xburst-qi_lb60-root.ubi -ROOTFS_UBIFS =openwrt-xburst-qi_lb60-root.ubifs -ROOTFS_TGZ=openwrt-xburst-qi_lb60-rootfs.tar.gz +LOADER = openwrt-xburst-qi_lb60-u-boot.bin +KERNEL = openwrt-xburst-qi_lb60-uImage.bin +ROOTFS_UBI = openwrt-xburst-qi_lb60-root.ubi +ROOTFS_UBIFS = openwrt-xburst-qi_lb60-root.ubifs +ROOTFS_TGZ = openwrt-xburst-qi_lb60-rootfs.tar.gz QI_IMAGE_URL=http://downloads.qi-hardware.com/software/images/Ben_NanoNote_2GB_NAND/latest/ QI_MIRKO_URL=http://downloads.qi-hardware.com/people/mirko/testing/ diff --git a/lm32/logic/sakc/firmware/boot0-serial/Makefile b/lm32/logic/sakc/firmware/boot0-serial/Makefile index 372e03a..1e227a7 100644 --- a/lm32/logic/sakc/firmware/boot0-serial/Makefile +++ b/lm32/logic/sakc/firmware/boot0-serial/Makefile @@ -30,6 +30,7 @@ image.lst: image image.bin: image $(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.bin + $(LM32_OBJCOPY) $(SEGMENTS) -O binary image image_bin.bin image.srec: image image.lst $(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.srec diff --git a/lm32/logic/sakc/firmware/boot0-serial/image.lst b/lm32/logic/sakc/firmware/boot0-serial/image.lst deleted file mode 100644 index 3b303e3..0000000 --- a/lm32/logic/sakc/firmware/boot0-serial/image.lst +++ /dev/null @@ -1,454 +0,0 @@ - -image: file format elf32-lm32 - -Sections: -Idx Name Size VMA LMA File off Algn - 0 .text 00000270 00000000 00000000 00000054 2**2 - CONTENTS, ALLOC, LOAD, CODE - 1 .rodata 0000001c 00000270 00000270 000002c4 2**2 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 2 .data 0000000c 0000028c 0000028c 000002e0 2**2 - CONTENTS, ALLOC, LOAD, DATA - 3 .bss 00000004 00000298 00000298 000002ec 2**2 - ALLOC - 4 .debug_abbrev 00000219 00000000 00000000 000002ec 2**0 - CONTENTS, READONLY, DEBUGGING - 5 .debug_info 000003d0 00000000 00000000 00000505 2**0 - CONTENTS, READONLY, DEBUGGING - 6 .debug_line 000002d8 00000000 00000000 000008d5 2**0 - CONTENTS, READONLY, DEBUGGING - 7 .debug_frame 000000a0 00000000 00000000 00000bb0 2**2 - CONTENTS, READONLY, DEBUGGING - 8 .debug_loc 000000fb 00000000 00000000 00000c50 2**0 - CONTENTS, READONLY, DEBUGGING - 9 .debug_pubnames 000000bc 00000000 00000000 00000d4b 2**0 - CONTENTS, READONLY, DEBUGGING - 10 .debug_aranges 00000040 00000000 00000000 00000e07 2**0 - CONTENTS, READONLY, DEBUGGING - 11 .debug_ranges 00000018 00000000 00000000 00000e47 2**0 - CONTENTS, READONLY, DEBUGGING - 12 .debug_str 0000017b 00000000 00000000 00000e5f 2**0 - CONTENTS, READONLY, DEBUGGING - 13 .comment 00000011 00000000 00000000 00000fda 2**0 - CONTENTS, READONLY - -Disassembly of section .text: - -00000000 <_ftext>: - 0: 98 00 00 00 xor r0,r0,r0 - 4: d0 00 00 00 wcsr IE,r0 - 8: 78 01 00 00 mvhi r1,0x0 - c: 38 21 00 00 ori r1,r1,0x0 - 10: d0 e1 00 00 wcsr EBA,r1 - 14: f8 00 00 03 calli 20 <_crt0> - 18: 34 00 00 00 nop - 1c: 34 00 00 00 nop - -00000020 <_crt0>: - 20: 78 1c 00 00 mvhi sp,0x0 - 24: 3b 9c 0f fc ori sp,sp,0xffc - 28: 78 1a 00 00 mvhi gp,0x0 - 2c: 3b 5a 02 a0 ori gp,gp,0x2a0 - 30: 78 01 00 00 mvhi r1,0x0 - 34: 38 21 02 98 ori r1,r1,0x298 - 38: 78 03 00 00 mvhi r3,0x0 - 3c: 38 63 02 9c ori r3,r3,0x29c - -00000040 <.clearBSS>: - 40: 44 23 00 04 be r1,r3,50 <.callMain> - 44: 58 20 00 00 sw (r1+0),r0 - 48: 34 21 00 04 addi r1,r1,4 - 4c: e3 ff ff fd bi 40 <.clearBSS> - -00000050 <.callMain>: - 50: 34 01 00 00 mvi r1,0 - 54: 34 02 00 00 mvi r2,0 - 58: 34 03 00 00 mvi r3,0 - 5c: f8 00 00 1d calli d0

- -00000060 : - 60: 34 01 00 01 mvi r1,1 - 64: d0 01 00 00 wcsr IE,r1 - 68: c3 a0 00 00 ret - -0000006c : - 6c: 34 01 00 0f mvi r1,15 - 70: d0 21 00 00 wcsr IM,r1 - 74: c3 a0 00 00 ret - -00000078 : - 78: 34 01 00 00 mvi r1,0 - 7c: d0 01 00 00 wcsr IE,r1 - 80: c3 a0 00 00 ret - -00000084 : - 84: c0 20 00 00 b r1 - -00000088 : - 88: e0 00 00 00 bi 88 - -0000008c : - */ -#include "soc-hw.h" - -/* prototypes */ -uint32_t read_uint32() -{ - 8c: 37 9c ff f8 addi sp,sp,-8 - 90: 5b 8b 00 08 sw (sp+8),r11 - 94: 5b 9d 00 04 sw (sp+4),ra - uint32_t val = 0, i; - - for (i = 0; i < 4; i++) { - val <<= 8; - val += (uint8_t)uart_getchar(); - 98: f8 00 00 57 calli 1f4 -uint32_t read_uint32() -{ - uint32_t val = 0, i; - - for (i = 0; i < 4; i++) { - val <<= 8; - 9c: 3c 2b 00 08 sli r11,r1,8 - val += (uint8_t)uart_getchar(); - a0: f8 00 00 55 calli 1f4 - a4: b5 61 08 00 add r1,r11,r1 -uint32_t read_uint32() -{ - uint32_t val = 0, i; - - for (i = 0; i < 4; i++) { - val <<= 8; - a8: 3c 2b 00 08 sli r11,r1,8 - val += (uint8_t)uart_getchar(); - ac: f8 00 00 52 calli 1f4 - b0: b5 61 08 00 add r1,r11,r1 -uint32_t read_uint32() -{ - uint32_t val = 0, i; - - for (i = 0; i < 4; i++) { - val <<= 8; - b4: 3c 2b 00 08 sli r11,r1,8 - val += (uint8_t)uart_getchar(); - b8: f8 00 00 4f calli 1f4 - } - - return val; -} - bc: b5 61 08 00 add r1,r11,r1 - c0: 2b 9d 00 04 lw ra,(sp+4) - c4: 2b 8b 00 08 lw r11,(sp+8) - c8: 37 9c 00 08 addi sp,sp,8 - cc: c3 a0 00 00 ret - -000000d0
: - -int main(int argc, char **argv) -{ - d0: 37 9c ff e4 addi sp,sp,-28 - d4: 5b 8b 00 1c sw (sp+28),r11 - d8: 5b 8c 00 18 sw (sp+24),r12 - dc: 5b 8d 00 14 sw (sp+20),r13 - e0: 5b 8e 00 10 sw (sp+16),r14 - e4: 5b 8f 00 0c sw (sp+12),r15 - e8: 5b 90 00 08 sw (sp+8),r16 - ec: 5b 9d 00 04 sw (sp+4),ra - int8_t *p; - uint8_t c; - - // Initialize UART - uart_init(); - f0: f8 00 00 40 calli 1f0 - - c = '*'; // print msg on first iteration - for(;;) { - uint32_t start, size; - - switch (c) { - f4: 34 0d 00 67 mvi r13,103 -{ - int8_t *p; - uint8_t c; - - // Initialize UART - uart_init(); - f8: 34 01 00 2a mvi r1,42 - - c = '*'; // print msg on first iteration - for(;;) { - uint32_t start, size; - - switch (c) { - fc: 34 0e 00 75 mvi r14,117 - 100: 34 0f 00 64 mvi r15,100 - case 'g': // goto - start = read_uint32(); - jump(start); - break; - default: - uart_putstr("**SAKC/bootloader** > \r\n"); - 104: 78 10 00 00 mvhi r16,0x0 - - c = '*'; // print msg on first iteration - for(;;) { - uint32_t start, size; - - switch (c) { - 108: 44 2d 00 08 be r1,r13,128 - 10c: 44 2e 00 16 be r1,r14,164 - 110: 44 2f 00 0a be r1,r15,138 - case 'g': // goto - start = read_uint32(); - jump(start); - break; - default: - uart_putstr("**SAKC/bootloader** > \r\n"); - 114: ba 00 08 00 mv r1,r16 - 118: 38 21 02 70 ori r1,r1,0x270 - 11c: f8 00 00 48 calli 23c - break; - }; - c = uart_getchar(); - 120: f8 00 00 35 calli 1f4 - - c = '*'; // print msg on first iteration - for(;;) { - uint32_t start, size; - - switch (c) { - 124: 5c 2d ff fa bne r1,r13,10c - size = read_uint32(); - for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) - uart_putchar( *p ); - break; - case 'g': // goto - start = read_uint32(); - 128: fb ff ff d9 calli 8c - jump(start); - 12c: fb ff ff d6 calli 84 - break; - default: - uart_putstr("**SAKC/bootloader** > \r\n"); - break; - }; - c = uart_getchar(); - 130: f8 00 00 31 calli 1f4 - 134: e3 ff ff fc bi 124 - size = read_uint32(); - for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) - *p = uart_getchar(); - break; - case 'd': // download - start = read_uint32(); - 138: fb ff ff d5 calli 8c - size = read_uint32(); - for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) - 13c: b8 20 58 00 mv r11,r1 - for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) - *p = uart_getchar(); - break; - case 'd': // download - start = read_uint32(); - size = read_uint32(); - 140: fb ff ff d3 calli 8c - for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) - 144: b5 61 60 00 add r12,r11,r1 - 148: 51 6c ff f6 bgeu r11,r12,120 - uart_putchar( *p ); - 14c: 41 61 00 00 lbu r1,(r11+0) - *p = uart_getchar(); - break; - case 'd': // download - start = read_uint32(); - size = read_uint32(); - for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) - 150: 35 6b 00 01 addi r11,r11,1 - uart_putchar( *p ); - 154: f8 00 00 31 calli 218 - *p = uart_getchar(); - break; - case 'd': // download - start = read_uint32(); - size = read_uint32(); - for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) - 158: 55 8b ff fd bgu r12,r11,14c - break; - default: - uart_putstr("**SAKC/bootloader** > \r\n"); - break; - }; - c = uart_getchar(); - 15c: f8 00 00 26 calli 1f4 - 160: e3 ff ff f1 bi 124 - for(;;) { - uint32_t start, size; - - switch (c) { - case 'u': // upload - start = read_uint32(); - 164: fb ff ff ca calli 8c - size = read_uint32(); - for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) - 168: b8 20 58 00 mv r11,r1 - uint32_t start, size; - - switch (c) { - case 'u': // upload - start = read_uint32(); - size = read_uint32(); - 16c: fb ff ff c8 calli 8c - for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) - 170: b5 61 60 00 add r12,r11,r1 - 174: 51 6c ff eb bgeu r11,r12,120 - *p = uart_getchar(); - 178: f8 00 00 1f calli 1f4 - 17c: 31 61 00 00 sb (r11+0),r1 - - switch (c) { - case 'u': // upload - start = read_uint32(); - size = read_uint32(); - for (p = (int8_t *) start; p < (int8_t *) (start+size); p++) - 180: 35 6b 00 01 addi r11,r11,1 - 184: 55 8b ff fd bgu r12,r11,178 - break; - default: - uart_putstr("**SAKC/bootloader** > \r\n"); - break; - }; - c = uart_getchar(); - 188: f8 00 00 1b calli 1f4 - 18c: e3 ff ff e6 bi 124 - -00000190 : -void sleep(int msec) -{ - uint32_t tcr; - - // Use timer0.1 - timer0->compare1 = (FCPU/1000)*msec; - 190: 78 02 00 00 mvhi r2,0x0 - 194: 38 42 02 90 ori r2,r2,0x290 - 198: 38 03 c3 50 mvu r3,0xc350 - 19c: 28 42 00 00 lw r2,(r2+0) - 1a0: 88 23 08 00 mul r1,r1,r3 - 1a4: 58 41 00 10 sw (r2+16),r1 - timer0->counter1 = 0; - 1a8: 34 01 00 00 mvi r1,0 - 1ac: 58 41 00 14 sw (r2+20),r1 - timer0->tcr1 = TIMER_EN | TIMER_IRQEN; - 1b0: 34 01 00 0a mvi r1,10 - 1b4: 58 41 00 0c sw (r2+12),r1 - - do { - //halt(); - tcr = timer0->tcr1; - 1b8: 28 41 00 0c lw r1,(r2+12) - } while ( ! (tcr & TIMER_TRIG) ); - 1bc: 20 21 00 01 andi r1,r1,0x1 - 1c0: 44 20 ff fe be r1,r0,1b8 -} - 1c4: c3 a0 00 00 ret - -000001c8 : - -void tic_init() -{ - // Setup timer0.0 - timer0->compare0 = (FCPU/1000); - 1c8: 78 01 00 00 mvhi r1,0x0 - 1cc: 38 21 02 90 ori r1,r1,0x290 - 1d0: 28 21 00 00 lw r1,(r1+0) - 1d4: 38 02 c3 50 mvu r2,0xc350 - 1d8: 58 22 00 04 sw (r1+4),r2 - timer0->counter0 = 0; - 1dc: 34 02 00 00 mvi r2,0 - 1e0: 58 22 00 08 sw (r1+8),r2 - timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN; - 1e4: 34 02 00 0e mvi r2,14 - 1e8: 58 22 00 00 sw (r1+0),r2 -} - 1ec: c3 a0 00 00 ret - -000001f0 : - //uart0->lcr = 0x03; // Line Control Register: 8N1 - //uart0->mcr = 0x00; // Modem Control Register - - // Setup Divisor register (Fclk / Baud) - //uart0->div = (FCPU/(57600*16)); -} - 1f0: c3 a0 00 00 ret - -000001f4 : - -char uart_getchar() -{ - 1f4: 78 01 00 00 mvhi r1,0x0 - 1f8: 38 21 02 8c ori r1,r1,0x28c - 1fc: 28 22 00 00 lw r2,(r1+0) - while (! (uart0->ucr & UART_DR)) ; - 200: 28 41 00 00 lw r1,(r2+0) - 204: 20 21 00 01 andi r1,r1,0x1 - 208: 44 20 ff fe be r1,r0,200 - return uart0->rxtx; - 20c: 28 41 00 04 lw r1,(r2+4) -} - 210: 20 21 00 ff andi r1,r1,0xff - 214: c3 a0 00 00 ret - -00000218 : - -void uart_putchar(char c) -{ - 218: 78 02 00 00 mvhi r2,0x0 - 21c: 38 42 02 8c ori r2,r2,0x28c - 220: 28 43 00 00 lw r3,(r2+0) - 224: 20 21 00 ff andi r1,r1,0xff - while (uart0->ucr & UART_BUSY) ; - 228: 28 62 00 00 lw r2,(r3+0) - 22c: 20 42 00 10 andi r2,r2,0x10 - 230: 5c 40 ff fe bne r2,r0,228 - uart0->rxtx = c; - 234: 58 61 00 04 sw (r3+4),r1 -} - 238: c3 a0 00 00 ret - -0000023c : - -void uart_putstr(char *str) -{ - char *c = str; - while(*c) { - 23c: 40 24 00 00 lbu r4,(r1+0) - 240: 44 80 00 0b be r4,r0,26c - 244: 78 02 00 00 mvhi r2,0x0 - 248: 38 42 02 8c ori r2,r2,0x28c - 24c: 28 43 00 00 lw r3,(r2+0) - return uart0->rxtx; -} - -void uart_putchar(char c) -{ - while (uart0->ucr & UART_BUSY) ; - 250: 28 62 00 00 lw r2,(r3+0) - 254: 20 42 00 10 andi r2,r2,0x10 - 258: 5c 40 ff fe bne r2,r0,250 - uart0->rxtx = c; - 25c: 58 64 00 04 sw (r3+4),r4 -void uart_putstr(char *str) -{ - char *c = str; - while(*c) { - uart_putchar(*c); - c++; - 260: 34 21 00 01 addi r1,r1,1 -} - -void uart_putstr(char *str) -{ - char *c = str; - while(*c) { - 264: 40 24 00 00 lbu r4,(r1+0) - 268: 5c 82 ff fa bne r4,r2,250 - 26c: c3 a0 00 00 ret diff --git a/lm32/logic/sakc/firmware/boot0-serial/image.srec b/lm32/logic/sakc/firmware/boot0-serial/image.srec deleted file mode 100755 index 178aecc..0000000 --- a/lm32/logic/sakc/firmware/boot0-serial/image.srec +++ /dev/null @@ -1,44 +0,0 @@ -S00D0000696D6167652E7372656314 -S113000098000000D00000007801000038210000B2 -S1130010D0E10000F80000033400000034000000C8 -S1130020781C00003B9C0FFC781A00003B5A02A08D -S11300307801000038210298780300003863029C9C -S1130040442300045820000034210004E3FFFFFD92 -S1130050340100003402000034030000F800001DE5 -S113006034010001D0010000C3A000003401000FDE -S1130070D0210000C3A0000034010000D001000022 -S1130080C3A00000C0200000E0000000379CFFF87F -S11300905B8B00085B9D0004F80000573C2B0008B4 -S11300A0F8000055B56108003C2B0008F800005228 -S11300B0B56108003C2B0008F800004FB56108004A -S11300C02B9D00042B8B0008379C0008C3A0000064 -S11300D0379CFFE45B8B001C5B8C00185B8D001469 -S11300E05B8E00105B8F000C5B9000085B9D00042E -S11300F0F8000040340D00673401002A340E007506 -S1130100340F006478100000442D0008442E0016BB -S1130110442F000ABA00080038210270F800004891 -S1130120F80000355C2DFFFAFBFFFFD9FBFFFFD67B -S1130130F8000031E3FFFFFCFBFFFFD5B8205800B7 -S1130140FBFFFFD3B5616000516CFFF64161000015 -S1130150356B0001F8000031558BFFFDF8000026D7 -S1130160E3FFFFF1FBFFFFCAB8205800FBFFFFC805 -S1130170B5616000516CFFEBF800001F31610000B5 -S1130180356B0001558BFFFDF800001BE3FFFFE614 -S113019078020000384202903803C350284200001D -S11301A0882308005841001034010000584100140D -S11301B03401000A5841000C2841000C20210001A0 -S11301C04420FFFEC3A00000780100003821029003 -S11301D0282100003802C3505822000434020000D1 -S11301E0582200083402000E58220000C3A0000068 -S11301F0C3A00000780100003821028C28220000EE -S113020028410000202100014420FFFE2841000471 -S1130210202100FFC3A00000780200003842028CB5 -S113022028430000202100FF286200002042001023 -S11302305C40FFFE58610004C3A00000402400009D -S11302404480000B780200003842028C28430000EE -S113025028620000204200105C40FFFE5864000445 -S113026034210001402400005C82FFFAC3A0000096 -S11302702A2A53414B432F626F6F746C6F6164651C -S10F0280722A2A203E200D0A0000000013 -S10F028CF0000000F0010000F00200008F -S9030000FC diff --git a/lm32/logic/sakc/system_tb.v b/lm32/logic/sakc/system_tb.v index b1234b0..3a211b5 100644 --- a/lm32/logic/sakc/system_tb.v +++ b/lm32/logic/sakc/system_tb.v @@ -52,8 +52,8 @@ initial begin $dumpfile("system_tb.vcd"); //$monitor("%b,%b,%b,%b",clk,rst,uart_txd,uart_rxd); -// $dumpvars(-1, dut); - $dumpvars(-1,clk,rst,uart_txd,uart_rxd); + $dumpvars(-1, dut); + //$dumpvars(-1,clk,rst,uart_txd,uart_rxd); // reset #0 rst <= 0; #80 rst <= 1; diff --git a/plasma/bootldr/bootldr.c b/plasma/bootldr/bootldr.c index d2d6735..21f38ba 100644 --- a/plasma/bootldr/bootldr.c +++ b/plasma/bootldr/bootldr.c @@ -239,7 +239,7 @@ int main(void) } break; case 0x3c: //raw test.bin file - ptr1 = (unsigned char*)0x10000000; + ptr1 = (unsigned char*)0xE00; for(i = 0; i < 1024*1024; ++i) { ptr1[i] = (unsigned char)ch; @@ -252,7 +252,7 @@ int main(void) break; //assume end of file ch = getch(); } - funcPtr = (FuncPtr)0x10000000; + funcPtr = (FuncPtr)0xE00; funcPtr(); break; } diff --git a/plasma/gpio/Makefile b/plasma/gpio/Makefile index cf5891b..6adb082 100644 --- a/plasma/gpio/Makefile +++ b/plasma/gpio/Makefile @@ -10,7 +10,7 @@ DUMP = $(CROSS)-objdump OBJCOPY = $(CROSS)-objcopy INC_PATH = ../include CFLAGS = -O -I$(INC_PATH) -Wall -c -s -ILDFLAGS = -Ttext 0 -eentry -Map $@.map -s -N +ILDFLAGS = -Ttext 0xE00 -eentry -Map $@.map -s -N LDFLAGS = -Ttext 0x10000000 -eentry -Map $@.map -s -N #Internal RAM 0x00 diff --git a/plasma/logic/ram_image.vhd b/plasma/logic/ram_image.vhd index 322eabc..49be336 100644 --- a/plasma/logic/ram_image.vhd +++ b/plasma/logic/ram_image.vhd @@ -45,27 +45,27 @@ INIT_00 => X"afafafafafafafafafafafafafafafaf2308000c241400ac273c243c243c273c", INIT_01 => X"8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f230c008c8c3caf00af00af2340afaf", INIT_02 => X"acacacac0003373cac038cac8cac8cac8c243c40034040033423038f038f8f8f", INIT_03 => X"000300ac0300000034038c8c8c8c8c8c8c8c8c8c8c8c3403acacacacacacacac", -INIT_04 => X"3c34ac343c34a42434a42434a42434a02434a02434a02434a02434a024343c27", -INIT_05 => X"8cac343caf008c34a730009434a330009034af008ca730009434a3300090ac34", -INIT_06 => X"008f300093af00008f8caf24008faf00343c8faf00008f300093af008c34af00", -INIT_07 => X"30008c343c0008af0000008f8caf00000000008faf000000000000008faf0000", -INIT_08 => X"2727038f8f8f0000140082260c82240c00142400100080afafaf270003ac3c10", -INIT_09 => X"8f240caf2727038f8f8f8f021626240c2608240c00102c3002242400afafafaf", -INIT_0A => X"8c001424ac00008c243c3c243c2703008f8c3c10000caf2730038c343c270300", -INIT_0B => X"0000000000000000000000000000000000000000000000000000000000002403", -INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", +INIT_04 => X"1c24001030008c24ac24ac9424003c00180003241c24a4248c0018ac2400003c", +INIT_05 => X"a00024241028302400a03c24243c3c0003001030008cacac242400003c000300", +INIT_06 => X"100010000c00102a0200260c24af08af2424240000afafafafaf270103001424", +INIT_07 => X"240c001a001427038f8f8f8f8f8f8f02240c240c000824102c24142c24142e24", +INIT_08 => X"008c34ac3c3c24240c3c240c3caf0cafafafafafafafafaf270008260c24240c", +INIT_09 => X"3c240c3c240c3c240c3c3c3c3c3c3c003c3c0c003c240c3c3c1430248c3c1030", +INIT_0A => X"0000142c2400000c240c3c270c260c260c260c260c240c3c240c3c240c3c240c", +INIT_0B => X"000c000c00000c240c3c3c08240c3c000c000c8e0000008c0024003c3c102c26", +INIT_0C => X"0200000010000c240c3c3c080002a208000c000c00000c240c3c0008923c08ae", +INIT_0D => X"000010000c240c3c3c080216a002260c00000010000c240c3c3c080216260c90", +INIT_0E => X"260c8c02240c3c00000010000c240c3c3c08240c000c000c0014002490020000", +INIT_0F => X"120008a23c24003c08240c3c021402240c000c260c8c021032021002240c000c", +INIT_10 => X"3c083c0c003c000c0014343c000c240c3c3c080000240016260c262610000c24", +INIT_11 => X"008c343c3c08240c000c000c2608240c3c000c020c240c3c00000c240c3c020c", +INIT_12 => X"82000c2682000c241400100082260c00240800100080afafaf270003ac001030", +INIT_13 => X"038f8f8f8f0216260c2424142c3002242400afafafaf272703008f8f8f001400", +INIT_14 => X"038c0014ac00248c3c24243c3c2703008f8c3c10000caf2730038c343c240827", +INIT_15 => X"6531006e706e724f303030206e6569612020740a00616d20423a20616f430a24", +INIT_16 => X"617965613673647475350a62697965340079617965330a7769796532006f6179", +INIT_17 => X"0a3d6541206820720a3e00616f446f42316f4600753900736838006979656137", +INIT_18 => X"00000000000000000000000000000000000037336820660a0d786e6e0a786e75", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", @@ -122,28 +122,28 @@ INIT_00 => X"b8afaeadacabaaa9a8a7a6a5a4a3a2a1bd000000a560a4a0bd1d8404a5059c1c", INIT_01 => X"b9b8afaeadacabaaa9a8a7a6a5a4a3a2a1a50086c6c406bb00bb00ba5a1abfb9", INIT_02 => X"9392919000405a1a06e0a606a606a606a6a50584e0029b401bbd60bb60bbbabf", INIT_03 => X"00e000c4e0000085a2e09f9d9c9e979695949392919002e09f9d9c9e97969594", -INIT_04 => X"028362420283620283620283620283a2028562028362028362028362028304bd", -INIT_05 => X"82824202a2004282a242004282a242004282a20062a242004282a24200a26242", -INIT_06 => X"00a34200a2a24300a382a24200a2a3624202a3a24300a34200a2a2008284a200", -INIT_07 => X"42006243020000a2004300a382a24302430300a3a243024302430300a3a20043", -INIT_08 => X"bdbde0b0b1bf0000400002100004040000511180400082b0b1bfbd00e0440240", -INIT_09 => X"bf0400bfbdbde0b0b1b2bf1211108400100084000040824412111080b0b1b2bf", -INIT_0A => X"a2006463404500624402054302bde000bf4202400000bfbd42e0424202bde000", -INIT_0B => X"00000000000000000000000000000000000000000000040000802400800042e0", -INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", +INIT_04 => X"c0c60040420062636284658205620205c000e084c0a582c6a200c0a202a20502", +INIT_05 => X"c2e5070740a285634040036642020300e000404200828283020382040200e000", +INIT_06 => X"54405300000040220312310090b000bf1514130000b1b2b3b4b5bd00e004c3c6", +INIT_07 => X"040000208095bde0b0b1b2b3b4b5bf4004000400000090404282404282400250", +INIT_08 => X"00434283020403840004840004b000b1b2b3b4b5b6b7bebfbd12003100040400", +INIT_09 => X"024400024400024400021e171615144002060000048400041543420382146063", +INIT_0A => X"0000404242400000440002c400e400c400a40084004400024400024400024400", +INIT_0B => X"4000400040000044000202004400024000000044008000444383030402406203", +INIT_0C => X"4200004040000044000202000040500040004000400000440002000044020050", +INIT_0D => X"0040400000440002020000136251100000004040000044000202000011100044", +INIT_0E => X"300044504400020000404000004400020200040040000000a0a683a543420000", +INIT_0F => X"1100005013110002004400020060130400400030004450400200601304004000", +INIT_10 => X"0200060000040000004363030000440002020000400240535200101040000002", +INIT_11 => X"0062a30502000400400000000300440002400040004400024000004400020000", +INIT_12 => X"02400010020000045100400002100040110080400082b1bfb0bd00e0a4004042", +INIT_13 => X"e0b0b1b2bf12111000646440624312111080bfb0b1b2bdbde000b0b1bf004000", +INIT_14 => X"e0a20083404584820563440302bde000bf6203400000bfbd42e06263030400bd", +INIT_15 => X"6d2e007374752074303078616b206d7262666957007320666f0a006474205342", +INIT_16 => X"64206d772e73646f6d2e007974206d2e007464206d2e006f74206d2e00726420", +INIT_17 => X"56207364006569654120007320526d2032702e006d2e0075652e0074206d772e", +INIT_18 => X"0000000000000000000000000000000000003834207769430a3e2074433e2065", +INIT_19 => X"0000000000000000000000000000000000000004000080240080000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", @@ -195,32 +195,32 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") RAMB16_S9_inst2 : RAMB16_S9 generic map ( -INIT_00 => X"00000000000000000000000000000000ff00000000ff18000700070005008500", -INIT_01 => X"000000000000000000000000000000000000012000002000d800d800ff700000", +INIT_00 => X"00000000000000000000000000000000ff00000100ff18000e000e000c008c00", +INIT_01 => X"000000000000000000000000000000000000022000002000d800d800ff700000", INIT_02 => X"0000000000000010000000000000000000010060006060000000000000000000", INIT_03 => X"0000000000201000000000000000000000000000000000000000000000000000", -INIT_04 => X"31030030300300220200210200200200000400000400000400000400000420ff", -INIT_05 => X"000055550000000300ff000002000000000400000000ff000002000000000031", -INIT_06 => X"0000000000001000000000110000001811110000100000000000000000000000", -INIT_07 => X"0000000020000000100000000000101a1011000000101c101a10110000001000", -INIT_08 => X"ff00000000001000ff0000000000000000000080000000000000ff10000020ff", -INIT_09 => X"00000000ff00000000000010ffff0000ff0100000000000010ff009000000000", -INIT_0A => X"0000ff00001000000500100500000000000020ff000100ff0000000020000000", -INIT_0B => X"0000000000000000000000000000000000000000000020000000202800000000", -INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", +INIT_04 => X"ffff00ff00000000000000000018301800000000ff0000ff0000000000282830", +INIT_05 => X"001000000000000c4000000c0c0000000000ff00000000000000202030000000", +INIT_06 => X"002000000200000090190002ff00000000000088900000000000ff100021ffff", +INIT_07 => X"0002000080ff00000000000000000010000200020000ff0000ffff00ffff00ff", +INIT_08 => X"000000002030000a02000a02000002000000000000000000ff9100ff02000002", +INIT_09 => X"000a02000a02000a02000000000000f810000028100a02000000ff3c00000000", +INIT_0A => X"90000000ff8000020b02000b020b020b020b020b020b02000b02000b02000b02", +INIT_0B => X"200280002000000b020000010b0200200200000000000000100c100000ff00ff", +INIT_0C => X"10108088ff00000c0200000100f80001200280002000000b0200000100000100", +INIT_0D => X"28300000000c0200000188ff00180002888098ff00000c0200000110ff000200", +INIT_0E => X"000000100c02008880980000000c0200000100022002000010ff200000101020", +INIT_0F => X"0080020d00279000010c020088ff180002200200000010ff0088001800022002", +INIT_10 => X"000100002810200000ff561200000c0200000100f80d80ff0002ff00ff00020d", +INIT_11 => X"000000200001000220022000ff010b0200200220000b02009000000b02002002", +INIT_12 => X"0020020000000200ff00000000000220000280000000000000ff00000010ff00", +INIT_13 => X"000000000010ffff02000000000010ff009000000000ff00001000000000ff00", +INIT_14 => X"000000ff00100000100c0c0000000000000020ff000200ff0000000020000200", +INIT_15 => X"6f20003a69204d680a303174656c6179696f6e61006866726f0000656c624100", +INIT_16 => X"0a726f20200a72207020007465776f20006520726f20007265776f2000642072", +INIT_17 => X"6100736400786e736400006866202066387920007020006d63200065776f2020", +INIT_18 => X"0404040404070404070606060606060505003e353169726f002068206f206820", +INIT_19 => X"0000000000000000000000000000000000000020000000202800000804040404", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", @@ -272,32 +272,32 @@ INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000") RAMB16_S9_inst3 : RAMB16_S9 generic map ( -INIT_00 => X"4c4844403c3834302c2824201c181410980e008004fd2a009800b000a800a001", -INIT_01 => X"504c4844403c3834302c2824201c181410003b2410200060125c1058fc005450", +INIT_00 => X"4c4844403c3834302c2824201c181410980e000704fd2a00b800d000b400b001", +INIT_01 => X"504c4844403c3834302c2824201c18141000812410200060125c1058fc005450", INIT_02 => X"0c08040000083c0048080c440840043c006000000800000801681360115c5854", INIT_03 => X"00080c000810121900082c2824201c1814100c08040000082c2824201c181410", -INIT_04 => X"31340030303000221400211200201000111400221300551200661100441000f0", -INIT_05 => X"000055550400003802ff00001800ff00001804000002ff00001600ff00000031", -INIT_06 => X"0004ff0000042100040004110004042111110404210004ff0000040000200400", -INIT_07 => X"020000200000f908121800040008210021000004082100210021000004081218", -INIT_08 => X"e020081014182100f6000001fb000dfb00030a210d0000101418e021080000fc", -INIT_09 => X"1049fb10e820081014181c06f4fc57fbfc3330fb00050a0f06fc1c211014181c", -INIT_0A => X"0000fa0400210000a800008800180800100000fd004310e80108002000180800", -INIT_0B => X"0000000000000000000000000000000000000000000000101020000020708408", -INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", -INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", +INIT_04 => X"f4fe00fc80000004000200004021004011000802fb0400fe00000700ff214000", +INIT_05 => X"00213037020a0fbf210800c7c00000000800fc8000000000d020214000000800", +INIT_06 => X"0c210e00880012102100013cc910db28080d0a212114181c2024d0210802f7ff", +INIT_07 => X"083c000821d930081014181c202428210a3c0d3c00d4a9111a9fed1abff10ad0", +INIT_08 => X"000050000000ff984600844600109314181c2024282c3034c802d8ff3c08203c", +INIT_09 => X"00f84600e04600b0460000000000000900028021009c4600000cff1c00001001", +INIT_0A => X"2100c20ad0210088d84600b446a846984680466c465846004046002846001046", +INIT_0B => X"214621b12100c5fc46000037244600214600b10000080000213c800000d416cf", +INIT_0C => X"212121219a00c50c4600003700090036214621b12100c5fc4600006d00003700", +INIT_0D => X"21217600c50c4600003721fb002101882121218900c50c4600003721fb013c00", +INIT_0E => X"04b100211c46002121211e00c50c460000370a3c214600b121fb210100212121", +INIT_0F => X"0b21010010102100371c460021f42b203c214604b10021f00f210e2b203c2146", +INIT_10 => X"0037028f210021a3001f783400c5204600003700090021f30188ff01fb008300", +INIT_11 => X"0000200000370a3c214621b1cf61244600214621b1f046002100c5dc4600213c", +INIT_12 => X"00213c0100003c0df8000d0000013c210a5721160000141810e000080021fc02", +INIT_13 => X"081014181c06f8fc3c5730020a0f06fc1c211c101418e020082110141800f500", +INIT_14 => X"080000fb0021040000b4940000180800100000fd008310e80108002000493c20", +INIT_15 => X"724d000a6f4f656500303020646967206e726769000a6c6f740000726f6f4b84", +INIT_16 => X"0065726d52006561204a00652072724d000a6265724d00642072724d000a7765", +INIT_17 => X"6c002072003e20736400000a6c7444724b2043000a44000a6b43000a72726d52", +INIT_18 => X"d8d8d8d8d8e4d8d840e09c5848180cd8b000203632746d6e0000656975006569", +INIT_19 => X"0000000000000000000000000000000000000000101020000020703cd8d8d8d8", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000",