From 0053d396924fbda954964b5d3430de3ae424e2c5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 13 Jul 2024 10:54:27 +0000 Subject: [PATCH] Deploy to GitHub pages --- .buildinfo | 4 + .nojekyll | 0 _images/GTKWave_Example2.png | Bin 0 -> 40810 bytes _sources/developer/getting_started.rst.txt | 225 + _sources/developer/glossary.rst.txt | 48 + .../developer/guide/cadpli/cadpli.rst.txt | 34 + _sources/developer/guide/index.rst.txt | 169 + .../developer/guide/ivl/attributes.rst.txt | 91 + _sources/developer/guide/ivl/index.rst.txt | 12 + .../developer/guide/ivl/ivl_target.rst.txt | 131 + _sources/developer/guide/ivl/lpm.rst.txt | 28 + _sources/developer/guide/ivl/netlist.rst.txt | 285 + _sources/developer/guide/ivl/t-dll.rst.txt | 61 + .../guide/misc/ieee1364-notes.rst.txt | 501 + _sources/developer/guide/misc/index.rst.txt | 10 + _sources/developer/guide/misc/swift.rst.txt | 68 + .../developer/guide/misc/xilinx-hint.rst.txt | 113 + .../developer/guide/tgt-vvp/tgt-vvp.rst.txt | 36 + _sources/developer/guide/vpi/index.rst.txt | 9 + _sources/developer/guide/vpi/va_math.rst.txt | 100 + _sources/developer/guide/vpi/vpi.rst.txt | 50 + _sources/developer/guide/vvp/debug.rst.txt | 19 + _sources/developer/guide/vvp/index.rst.txt | 13 + _sources/developer/guide/vvp/opcodes.rst.txt | 1357 ++ _sources/developer/guide/vvp/vpi.rst.txt | 169 + _sources/developer/guide/vvp/vthread.rst.txt | 64 + _sources/developer/guide/vvp/vvp.rst.txt | 1246 ++ _sources/developer/index.rst.txt | 15 + _sources/developer/regression_tests.rst.txt | 125 + _sources/developer/version_stamps.rst.txt | 37 + _sources/index.rst.txt | 25 + _sources/targets/index.rst.txt | 23 + _sources/targets/tgt-blif.rst.txt | 44 + _sources/targets/tgt-fpga.rst.txt | 201 + _sources/targets/tgt-null.rst.txt | 7 + _sources/targets/tgt-pal.rst.txt | 8 + _sources/targets/tgt-pcb.rst.txt | 61 + _sources/targets/tgt-sizer.rst.txt | 49 + _sources/targets/tgt-stub.rst.txt | 30 + _sources/targets/tgt-verilog.rst.txt | 6 + _sources/targets/tgt-vhdl.rst.txt | 82 + _sources/targets/tgt-vlog95.rst.txt | 101 + _sources/targets/tgt-vvp.rst.txt | 63 + _sources/usage/command_files.rst.txt | 198 + _sources/usage/command_line_flags.rst.txt | 444 + _sources/usage/getting_started.rst.txt | 167 + _sources/usage/gtkwave.rst.txt | 118 + .../usage/icarus_verilog_extensions.rst.txt | 90 + _sources/usage/icarus_verilog_quirks.rst.txt | 47 + _sources/usage/index.rst.txt | 25 + _sources/usage/installation.rst.txt | 183 + _sources/usage/ivlpp_flags.rst.txt | 146 + _sources/usage/reporting_issues.rst.txt | 76 + _sources/usage/simulation.rst.txt | 495 + _sources/usage/verilog_attributes.rst.txt | 35 + _sources/usage/vhdlpp_flags.rst.txt | 59 + _sources/usage/vpi.rst.txt | 246 + _sources/usage/vvp_debug.rst.txt | 148 + _sources/usage/vvp_flags.rst.txt | 116 + _sources/usage/vvp_library.rst.txt | 29 + _static/alabaster.css | 701 + _static/basic.css | 905 ++ _static/custom.css | 1 + _static/doctools.js | 323 + _static/documentation_options.js | 12 + _static/favicon.ico | Bin 0 -> 1150 bytes _static/file.png | Bin 0 -> 286 bytes _static/forkme_right_darkblue_121621.png | Bin 0 -> 4787 bytes _static/jquery.js | 10879 ++++++++++++++++ _static/language_data.js | 297 + _static/minus.png | Bin 0 -> 90 bytes _static/plus.png | Bin 0 -> 90 bytes _static/pygments.css | 74 + _static/searchtools.js | 532 + _static/underscore.js | 2042 +++ developer/getting_started.html | 301 + developer/glossary.html | 152 + developer/guide/cadpli/cadpli.html | 151 + developer/guide/index.html | 301 + developer/guide/ivl/attributes.html | 207 + developer/guide/ivl/index.html | 132 + developer/guide/ivl/ivl_target.html | 237 + developer/guide/ivl/lpm.html | 146 + developer/guide/ivl/netlist.html | 366 + developer/guide/ivl/t-dll.html | 175 + developer/guide/misc/ieee1364-notes.html | 578 + developer/guide/misc/index.html | 130 + developer/guide/misc/swift.html | 191 + developer/guide/misc/xilinx-hint.html | 228 + developer/guide/tgt-vvp/tgt-vvp.html | 151 + developer/guide/vpi/index.html | 129 + developer/guide/vpi/va_math.html | 216 + developer/guide/vpi/vpi.html | 166 + developer/guide/vvp/debug.html | 140 + developer/guide/vvp/index.html | 132 + developer/guide/vvp/opcodes.html | 1390 ++ developer/guide/vvp/vpi.html | 267 + developer/guide/vvp/vthread.html | 177 + developer/guide/vvp/vvp.html | 1217 ++ developer/index.html | 130 + developer/regression_tests.html | 225 + developer/version_stamps.html | 153 + genindex.html | 107 + index.html | 165 + objects.inv | Bin 0 -> 1365 bytes search.html | 126 + searchindex.js | 1 + targets/index.html | 144 + targets/tgt-blif.html | 161 + targets/tgt-fpga.html | 303 + targets/tgt-null.html | 129 + targets/tgt-pal.html | 132 + targets/tgt-pcb.html | 182 + targets/tgt-sizer.html | 169 + targets/tgt-stub.html | 151 + targets/tgt-verilog.html | 131 + targets/tgt-vhdl.html | 195 + targets/tgt-vlog95.html | 204 + targets/tgt-vvp.html | 181 + usage/command_files.html | 304 + usage/command_line_flags.html | 512 + usage/getting_started.html | 281 + usage/gtkwave.html | 232 + usage/icarus_verilog_extensions.html | 210 + usage/icarus_verilog_quirks.html | 169 + usage/index.html | 151 + usage/installation.html | 294 + usage/ivlpp_flags.html | 285 + usage/reporting_issues.html | 193 + usage/simulation.html | 581 + usage/verilog_attributes.html | 163 + usage/vhdlpp_flags.html | 183 + usage/vpi.html | 357 + usage/vvp_debug.html | 270 + usage/vvp_flags.html | 233 + usage/vvp_library.html | 155 + 136 files changed, 38950 insertions(+) create mode 100644 .buildinfo create mode 100644 .nojekyll create mode 100644 _images/GTKWave_Example2.png create mode 100644 _sources/developer/getting_started.rst.txt create mode 100644 _sources/developer/glossary.rst.txt create mode 100644 _sources/developer/guide/cadpli/cadpli.rst.txt create mode 100644 _sources/developer/guide/index.rst.txt create mode 100644 _sources/developer/guide/ivl/attributes.rst.txt create mode 100644 _sources/developer/guide/ivl/index.rst.txt create mode 100644 _sources/developer/guide/ivl/ivl_target.rst.txt create mode 100644 _sources/developer/guide/ivl/lpm.rst.txt create mode 100644 _sources/developer/guide/ivl/netlist.rst.txt create mode 100644 _sources/developer/guide/ivl/t-dll.rst.txt create mode 100644 _sources/developer/guide/misc/ieee1364-notes.rst.txt create mode 100644 _sources/developer/guide/misc/index.rst.txt create mode 100644 _sources/developer/guide/misc/swift.rst.txt create mode 100644 _sources/developer/guide/misc/xilinx-hint.rst.txt create mode 100644 _sources/developer/guide/tgt-vvp/tgt-vvp.rst.txt create mode 100644 _sources/developer/guide/vpi/index.rst.txt create mode 100644 _sources/developer/guide/vpi/va_math.rst.txt create mode 100644 _sources/developer/guide/vpi/vpi.rst.txt create mode 100644 _sources/developer/guide/vvp/debug.rst.txt create mode 100644 _sources/developer/guide/vvp/index.rst.txt create mode 100644 _sources/developer/guide/vvp/opcodes.rst.txt create mode 100644 _sources/developer/guide/vvp/vpi.rst.txt create mode 100644 _sources/developer/guide/vvp/vthread.rst.txt create mode 100644 _sources/developer/guide/vvp/vvp.rst.txt create mode 100644 _sources/developer/index.rst.txt create mode 100644 _sources/developer/regression_tests.rst.txt create mode 100644 _sources/developer/version_stamps.rst.txt create mode 100644 _sources/index.rst.txt create mode 100644 _sources/targets/index.rst.txt create mode 100644 _sources/targets/tgt-blif.rst.txt create mode 100644 _sources/targets/tgt-fpga.rst.txt create mode 100644 _sources/targets/tgt-null.rst.txt create mode 100644 _sources/targets/tgt-pal.rst.txt create mode 100644 _sources/targets/tgt-pcb.rst.txt create mode 100644 _sources/targets/tgt-sizer.rst.txt create mode 100644 _sources/targets/tgt-stub.rst.txt create mode 100644 _sources/targets/tgt-verilog.rst.txt create mode 100644 _sources/targets/tgt-vhdl.rst.txt create mode 100644 _sources/targets/tgt-vlog95.rst.txt create mode 100644 _sources/targets/tgt-vvp.rst.txt create mode 100644 _sources/usage/command_files.rst.txt create mode 100644 _sources/usage/command_line_flags.rst.txt create mode 100644 _sources/usage/getting_started.rst.txt create mode 100644 _sources/usage/gtkwave.rst.txt create mode 100644 _sources/usage/icarus_verilog_extensions.rst.txt create mode 100644 _sources/usage/icarus_verilog_quirks.rst.txt create mode 100644 _sources/usage/index.rst.txt create mode 100644 _sources/usage/installation.rst.txt create mode 100644 _sources/usage/ivlpp_flags.rst.txt create mode 100644 _sources/usage/reporting_issues.rst.txt create mode 100644 _sources/usage/simulation.rst.txt create mode 100644 _sources/usage/verilog_attributes.rst.txt create mode 100644 _sources/usage/vhdlpp_flags.rst.txt create mode 100644 _sources/usage/vpi.rst.txt create mode 100644 _sources/usage/vvp_debug.rst.txt create mode 100644 _sources/usage/vvp_flags.rst.txt create mode 100644 _sources/usage/vvp_library.rst.txt create mode 100644 _static/alabaster.css create mode 100644 _static/basic.css create mode 100644 _static/custom.css create mode 100644 _static/doctools.js create mode 100644 _static/documentation_options.js create mode 100644 _static/favicon.ico create mode 100644 _static/file.png create mode 100644 _static/forkme_right_darkblue_121621.png create mode 100644 _static/jquery.js create mode 100644 _static/language_data.js create mode 100644 _static/minus.png create mode 100644 _static/plus.png create mode 100644 _static/pygments.css create mode 100644 _static/searchtools.js create mode 100644 _static/underscore.js create mode 100644 developer/getting_started.html create mode 100644 developer/glossary.html create mode 100644 developer/guide/cadpli/cadpli.html create mode 100644 developer/guide/index.html create mode 100644 developer/guide/ivl/attributes.html create mode 100644 developer/guide/ivl/index.html create mode 100644 developer/guide/ivl/ivl_target.html create mode 100644 developer/guide/ivl/lpm.html create mode 100644 developer/guide/ivl/netlist.html create mode 100644 developer/guide/ivl/t-dll.html create mode 100644 developer/guide/misc/ieee1364-notes.html create mode 100644 developer/guide/misc/index.html create mode 100644 developer/guide/misc/swift.html create mode 100644 developer/guide/misc/xilinx-hint.html create mode 100644 developer/guide/tgt-vvp/tgt-vvp.html create mode 100644 developer/guide/vpi/index.html create mode 100644 developer/guide/vpi/va_math.html create mode 100644 developer/guide/vpi/vpi.html create mode 100644 developer/guide/vvp/debug.html create mode 100644 developer/guide/vvp/index.html create mode 100644 developer/guide/vvp/opcodes.html create mode 100644 developer/guide/vvp/vpi.html create mode 100644 developer/guide/vvp/vthread.html create mode 100644 developer/guide/vvp/vvp.html create mode 100644 developer/index.html create mode 100644 developer/regression_tests.html create mode 100644 developer/version_stamps.html create mode 100644 genindex.html create mode 100644 index.html create mode 100644 objects.inv create mode 100644 search.html create mode 100644 searchindex.js create mode 100644 targets/index.html create mode 100644 targets/tgt-blif.html create mode 100644 targets/tgt-fpga.html create mode 100644 targets/tgt-null.html create mode 100644 targets/tgt-pal.html create mode 100644 targets/tgt-pcb.html create mode 100644 targets/tgt-sizer.html create mode 100644 targets/tgt-stub.html create mode 100644 targets/tgt-verilog.html create mode 100644 targets/tgt-vhdl.html create mode 100644 targets/tgt-vlog95.html create mode 100644 targets/tgt-vvp.html create mode 100644 usage/command_files.html create mode 100644 usage/command_line_flags.html create mode 100644 usage/getting_started.html create mode 100644 usage/gtkwave.html create mode 100644 usage/icarus_verilog_extensions.html create mode 100644 usage/icarus_verilog_quirks.html create mode 100644 usage/index.html create mode 100644 usage/installation.html create mode 100644 usage/ivlpp_flags.html create mode 100644 usage/reporting_issues.html create mode 100644 usage/simulation.html create mode 100644 usage/verilog_attributes.html create mode 100644 usage/vhdlpp_flags.html create mode 100644 usage/vpi.html create mode 100644 usage/vvp_debug.html create mode 100644 usage/vvp_flags.html create mode 100644 usage/vvp_library.html diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 0000000000..4e3bfc1d62 --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 310eb518ac2147d317a98d36826c77cd +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/_images/GTKWave_Example2.png b/_images/GTKWave_Example2.png new file mode 100644 index 0000000000000000000000000000000000000000..2de993933e9ad55768a88dc74d3fd1e4255141de GIT binary patch literal 40810 zcmaI8WmH^E(=I$nZ~_SsTmr$}9Rk7K-5myZhd_Yfu7d=3cXtRnxVsJRt{?YvKkxa@ zkF(xhJ!^XP?%mzfyLNS5S5;4_f}A)i5*`u&06>+L5K#gEU{nAAC?^Ey_nHRw_44;G zM0*KMCjj7M-#;IyMB0z|000R0`2SSEUT8H(KVnFX5dVAK zD+t!_-==4uK0kl@Pq9rrg{APdsuO$g62~}9Oam719RaGx{}Y^yaspKtf?^KU6iN^2 zZ_=b8@>;LAE3qrNe};k;Qc+y&)?dg-At$!W|Ms^w-*SJEPD>bfSz`1!-{EcsGbkMo z$CUEWNm)~|%Y|1{L}%QPy(d6+d(D0h@t=v4{4Sy4y~lw4%1R#{o86|v!>fx57#rZ8 zJu(_Uq62&Iam%Je+TrI8-JYaQtsU@8c9v43}KBVfFgpe097_w~NaAZAVWQH$YtZQq~L& zN!RDGx%%N~Cy)N7KK$`DqTB@4Q&WLWDU}t~OPfjtH#M$+{O_DL6wWs(se(L^uSxmX zrfSmX&eJa%eFI5xoartBB*UVqbGDP&##dr`whdpzls4G7EkotA_)rAA9zB)HV@n~< zOpH&4jLb*JQ)Q62bQqf&x#k&cO&02a{LRV7M7}QKNwq8*NgMJn`|^?;-Io z-qpNPfbRq4W@VWR5@Ek~0+AulSoF{&sv`$L3b?=a1I1_Nwy5OQFz*k(HTQT!9yHj$ zK2}KnxA-T`sa%ITetcid^9m*dyG}TB!=2iI;DkYhv0W*UojIyAnGs0?MA^1kh5@Tc zVX`v|T)OUXk)eVG;DiTIvDY|WR6Aaj^oPKml^8iD6tBmmX1SJ^f483Mj~wCD2irGD z;O?J@EZ*O1C@L0{O7I=JGa&#hfcnHh8Xi^Hf$4eW006L;crfN~GzmhE(XyK@<0GUh zyO*X@Z8At&o?7|+;ZMX->)~T&LM1HquD7?PV~{ZKrG^7z zS7>N}>BvFp0A~!q&u{vAHu(w)5J+`S^@oXhpk?ts6+@d_qKe~i0bJ_JKl%mgGqK>% z!^BX!WAS!APg0tA^Sygd@vX82FixNA}Y zO+MyATf}`8{@|N{Gg;~f%hkz|j(v+Dr&ryZ#o$&Rz#lr^aZTnD2C{+UC!^PHkxwzh zCxLqHJZ!fP4GJW>uEGnE+kS6O?0VrN<$*{?g>5r2ih+vA=JmCrOEEUcNtsdu1yC4Y zWS_c_E>B-OHU|AXw?5~01x3+4_ z&^2V0C#!WYT1am>#+--ecIvXr&X<)o-9_7H87mi%>WOp~xm;B$UsD?8&8fD*kP{dm z-SS8axr|gy7u&%!vQGqnzXaMSxRZrJg&z{}-HvwFm{{UMNY>H~e}p9dextE_8b1lP zsJx_3xXSG8$t5!WZm?Y}5kB!HHC(x;POW~&|Bt=9!OeIttk4Xd$x@RK1}m)pG`Lc` zne*O~gBJR?wXd4d!VSitZN34zXp}j3)ULZ66#|FI&uy-#U9JlI&j1CrF~L_WM_PC| z$ggAF7H3GWbuS;o;{^skT%Y^Brv#Mdle@O^*0j?gu~k)HZd4&G70}KO2unf{91Jl6 zEKSvB*6PG#UhJP{gvdL6bIly{l+9o*`w8uj+Uia&2|L`RsNnMf05HYH*%>1l4bp8& zr-N3yM|rh+?X!&p;zI;|?nzkW557$JT+Y|Fw5pi@krXX9ym`?*itcle&@`V|7#~*~ z6N|F446=W$U+2`7!l0!Rj@`*Y zDzj+du+rA_+|1v&YWpO~NQ*uIw22X;Vp_PET7R03)@9c#}_nCU{VxPuUzZjj?fl zM6AaRh&Q{rS=4~_Oz>=d+lb)}f7U0au*5K2OpLQ~Z<)7J?0C%E1lxB+@t3+vwk-w@i@jFFqi>tz3uj z`&C8Xbv3V7QJ8g6W~`hKmRnzti&Cu!#5-I(i7x+$Y-M~ltm3t?w)1?8X7uHW*Y=yL zu_R8BvYNk9$&{Gn(@zV(KUyZIR1zJoSXLKAxk&PIKG^ZH0!pc}=r~3rVyPF%9{pU^ zF+~89y=t~Rf6vo`9sWBcIS#GBLEpkz`&~k1eU-&;_kqo1+IO#!3?D$+cmu1LeTlbB zvu>yDJY-e(mZ*^*w@lA#^aDT|4TTO@b)k^QHyH*!Kso?z(1q|dcCdI;3+UFYM-~SC z#Uny=O8h(eS>AKq!hRt|Lj^~Pl}|2O+`R2<_G_d~;}r7XO_-*kp`?+n`qI?$;Nr++ zVE5tqAoJo-cC}HUmVkhqJi!V%LKVfcL&UqOQftd+A(FMHrxuoD_aO$9I`qlj=rA!n z+lTKN(|7De)>Z_by|kZ%`RTTQxf#db;mY0^ouokRja>T?dnj?LzJZXCK-Id4S=Flx z4cQB`t|HU}J6V2Jg>O7xKMfDt&-!JYCtQq^i8bEf_MqFvFUaCtI{f@uKHc%iu?R1` zWe4+1E3H3rt0Q-6uZoc{51cX*wTdGwI8cyzcQV(U6!6>fYj$x?Bdg8vp%GMnKxeXf z)2}ev+N2QtKtOGFVU%cz=(~hwpcldcLgPWKfq*Od3SD^&0LjVW?0NLzleDz0Kgn;r z+rtZe_JpS{@lkqqvL8}T1AhZNoat!Ug@LD3;m!FRbTJuyNPMm(mBV54gR81nbaTMJ zMYaL%Pkjl$z7c6lQYX6kpe?p5@K>R^(R=@em0LZxj489SL}X5u+nYU80*^MYCU}&L zjc`1JRL~(CI}?yYK>3>%eqN^yvzHlu0PesPEm6 z_aF$70PPe?&{eNf=?aZ%>WoQ&S^-OMKtyOpVwh(deMcPvIDXO!b=w$L2mlzhyyOM| zuAd_{6u#Mu)a^VxBo~Yva20!A&?=_-k5qEeorA@p?V+2qDSs!Ii0Ru{=5Ke>lxqtq z?NXm5Tx}IK-l@W!d5bY4U~vy2^2vGTAre?;d?|(jbomcm5y4)3?BZ@5hrcVGpNgol z6tuJ&Ptr9fCNJ@j`kJizq7+pxFaPY!W%~@-PFq@F%V3hv*6P^XQKp9j2vD%;EKf@H z-#1tUQ+;Kj(+L!c@OlCqaTjxG)R`h#qd3{2)VjvL${#x+Wt^ZM4m&OTta} zyEC$v+ioxuXcy-NO^^)eH{%%Yo9-Fs7~L1FeHM#zdYc#*w?YBk9qUOT$xoKuulgRSmn^GP;SXP!q}>c#yGpv@n+0TiGtO&bH8&=nhS!MD)9(Hm|9t zV?hi$1|!>@QOZ(BX4p}5-JkOk?QkIzHcp|ouZbv2QkACn`TH=$iIOGn1{`TVosQ{e z-257oguRHK2<93COp1tn5Q;HVjfu!7pwov$Zex>vjh129kJ7udhl->KIcA$}+RJl9 zHK|J@(+g96U1ee~)m>MZV+txR47(}P9d)+V6n=A*C+TB&C@+^zxrwxIA61Pf#D9r6 z3Hd68iIL<53wTgK1F&zn;()u1xq$DZNNB8Wxf;aS8Gk>_#HFy|v&i{Sf{QirJL6G)72PDi<2=fHX~E(PA&BJIUwagLyT5YU%%sB(IS>n?S>ae)eYA2o`K=t z!W!5fmnu~7d#Zn#Nb)n>a>W=hDVu3O{Poi`6=-dOXpAiKukK{FLn>_(6G~!JmQ%!S zGHSN;WtV2RIa@qA8mp`YO@H15y6+r9%!Nn=1Ki_Fu-}AYlX`~TaFegPLYTK#z6Vjg z>sWi9?(7OB(n1_uBTP(T63%Q>3bw-DNAK7*X{leH_V;FKyQ53^zW?~!bTb%-^}t$qbIx>mc=Mn$n})S~YO?z) zgd)th-U6Wb@{LUn7SNSeHKEbH9uC!&c0O1g{0D}T;K`-^U>}OUT_>$hS!9i`;YFp8 zSvO2@aadfhgI!g^Bwxbi@FS{6p+SDo+fI6NxQWU=*D?(xXi^_Y$

4l&z6Vq>2yp8 z&AC>V;$Jr;l8W2=R)oGdX`=$_({N15YZgPTUx@agV9LiUq&#m`?oJBiUp2hXRENK# z!(P0dWjsK029T`%IL&?ib-8vG0`TxQU@-^+C4%T~<%INwHyiJavJJZIpWD4@)ji&J zZP#pMs6|?Q{zaKts1&QzvoE+SO9_|W)BX!!aHDw zj$no}z=7M?!yn^)2V#CvDZZD>ij?cF4DZ-HE0OSd?6mz26%zOl;(f1y`TL#!U-Wy2 zfcW~KI+8WAZ}(*XUXG60ct=d{4Yv4&0|fuuP@;RfW18ZckpFeM==Y!6-zXq=(2XwyQahmD!e;9zbRB7yS%$N9xhyQKF z|L4?Zbj~R$o&~tl~(RBtwrZNeWV`Acg9 zP!jK}_>A4Ib$)lMW4D%(-sX}=V?|J`^v~~mlgJMgOs{v-Aw#Qd2@-S}H~|aG8N04O z`}lt-x$sV0N)M4g@=$MbOfC%D5&6ByMPlFcbHz%hq&`+WS!RE^r&DotfKZU&ZZ%5V za@X#X9<;CCsPW=HdvjiLw0M4{{0v;C#$q~VJnLfin(l*4|C(T5^*QonPj%bODDM;I zy4n~N5~>B4hRb0pyGB?~?JXM+-k6nQnx7D2PnZo6zKY6y_9Z4b-(=kE0Sy7(DUS=k z$l~Figy|wdu=jy}zKdQr{u+V*>+P`Q72}8Tb^Dt5WERG~wV+k)x0Xc%E2km+5g{yV zcMEs<#?ysD`VQvThvBU+cD$g3j6&o6%pdYkQBH+W-?7^uOh=nv<-JB0OE66)4Go_1 zYj3lLET)%hNCq%6iI&{vv+vRY56fft|L`s|Mf0;K;Z8qXefV39YXR$z^t_RJo@`=o zQus6h@_bJ(MHNuKudg;C;AP@$+Ek3&owC=FGvN3b;^lS85$}Dpd-c|JSOUe({V8Hrbq-@apQHCA_oxk~+k z`{CpY>I8od8R1yKW;)|uTU+34xxH^R7py$nm}Sk49dcMK8lGc=>`c`> z!7zZLw7VliU!Sw;JP6Ps`j$AXY`L)#O?S&l&&=#n-iK&m8-fl6_%$)>({_ZihE4_m z_}PgLe$mgEPO6=?@^~2k{4UBi&y!n`tWOO<1xAvpWlBMP$x0=gf0V-8pdNU-!)U7` zHGa;#PS-U^kSUT zJ$b!rJW^V&;B!9OyC`=`%hzej)XR_ZvwV5=(II~J;hI8EvwjAV=m0*L3KuVCdM8ba-F&q<}E#?{Aq&Ip@zf| zQ#lgos^mz~?s%MyP9&4-v!35px}HD*OTO`yyxFy5QTMs(o*-}p{6i*iUWRyPO0Y<^ z({dzQ#EM3l;2ZnhA&X5Bq&>Vb6AjP!IoO9|0jwnU6Wzt+&Zf};nbLd1ijLFOn$Kdb zupG78zt6AF+~-K+Z=TuBqf2>Z6pFkLVY0bo*Kc_*50E65Yq=*|W3bqdLYE>NI>jdE zV0GJay2E9)9RDGmvWZd8Q ztCHSMdL(6{q(!4nZK7mcDAwMYHak{eWqfTBt@naAK=k+|0PkN5J`?P3#GRNd5y9Iv zh0}zE^AOW*Po>{mX(1wJvb64{oVP9QkHDWd@(I8Lsd&^GT%dKzL&)8l!dMk(J`4c= zMliq5IX0X2eqs&bUKeoZ2om`ZYut92(&@-RVPvIL@;VTp=8KF(`88Kh^(crI=mgLa z@eCgBo-EtY8eZUCQjArVX&_Y^{9=sVfP+k85qC=Td=TD@Q6uw_(PWr5ieW2Db^Xot z(N?A<4TA|za+{->GzIX^_i!Wyt1(_^TD8pdk5xo){q37sV8UWnLOgFf=OLmL9iaH2 z4HX>wH&PZ!D?3J{=UpQHSwa96h#@eoV)^{!&{}t1RY4sorfcKqMf+> z*+NNRh>Z6UDxbQQbEUe{q<{;dG5_^0y7!$|TA2lZ%B;&1%FWU>mpcoxqVvki=&sJl z&5WzW03_ci6KB(YqC-dMQ^({aevE{VI<4LwJ@7(ol3wipwB0zS?_N6|4N8XR2GJJH zoEY;EQn$GqB(A!T67+x2jM*ou74_-^DVb-l(}YB?${@Xa9M%&Rn-Oe-`bH2)xAC>se)Xz_?V|!+1@R%*;n;VhW4(jT% zz6|y@8rR+g{HBI26H~rXAEg4l?=iP$!(g}I`IG7S)`&ml0izN}oX84UD~>vAdByyq z^GHZLuZxaJ$QEjqVrNw}?X~yktECOABNIogXJg3vK_)ny{ol_^)x7Hq0eY8Hz*(@E!+oX;`UU(`q96b87foSQx zLys$U6{z?PxaX^cU^UcX-$kTdKIhq`q1*W{*LD~auA|XkU3fnv*eZIKTABH&=GC~| z7=37!L*}fsaP+z@3Zhg#rj6&9-1dEutt`h`C;MZ#oPET~%kY|GJ_O~JNOFNcQRr$V z>^tFqDrZVWfHjji)#>3Qmy3dMnFp29A{3eG-Jy6D%>G=E@~-YB4d#QE3RjYwspXW=usr8aigrT?#^tB*JI|M$w;Ecmbg>^aNp)3a!BNL#=6 zzt_?20JvBGTaW*j>rIdEeDfd6eeZwpfh@XkQ1tB=FR;E!-*#gx@qZuy!j=p51*!Se ziS++6&;P5}lw`(t-(={}P&ARCtFwI(I?k1YLly>xHp?-!!FKr*28Q~5AqX^5^oh9LC=E+mPLkj4!cj#==6ae7P^3H3 zzdBZ~dxUm;V!hUzF!B>hZ<|w!a#x(Ih;O|bg_;l5^2* zOCCkIXJQ&%_9(JWY&eNf8+Rh=tCF&E2nwF(R-YpO$Z+1&XQ!-uLEwuJi1+UFfzw)J z2v%81$qbyPz1OXPDQvMTKSG;omb$gQ^}2Kyt(8HHzG1^P$~4euC#YF{34wa?Y;I}k zklHf+EPAmY%IZhV^Jv&O9{6}$uDXl`^R4jPU|-+Z+i6JVYK!yP)X$uf>AgpNnP$Gj zdwr~iK#O8k_Bnp^o0r`_9}P^)FxxYphVY}EsSy#=^(CUm-GD#JmFda=e_1pE+`ZPm z)iQ?zO-iHrjL22G-_SWlNl`CPP2loa`lK(3K3>zk#e&}U^#jVUC!2NMYwI)B&wmD# zeR~IFQf?b+&*i#sI=4#kC1mm1JZ14ddwkCFdDhZ#7q%5nOT!jnHBK#Wu2KHuvn&?H zLLG=s`jzA&Se4@*2B3%u;;?zWw#);COHUrWKVX_fDT;Vi%idtHr>(7Ae|Tz2iW;?M zpt$;-?qa7>=}`Z7OB=7H<~iGmuJ(OsdaW6G3HOF=@JU!+C;D&4e9NO(CvVVA8JA`+ zszX0#Kn@jyRzn=5slL?DxvCLcMDHJYOP~>@=bWdIg>HDQHlD0W)CXrO&T1TXrZ{?B zZmB^ityPv#iw9ar_bSPWaOQk+l&sRqC0`)dS^0sTl&SL#!Q;W(AS3*4EXzy4^YcC*Pi* zzvqkV>*|IEII+2+tDRSy6)(2xmMX~8aGnM<(C2?*0r=jLIu@h-bsuijuCHeO)X?N7 zfJIuYHKT2PiWj;f8;K;l8g`XGI(agV z;JBb6UE`K$MIUrD%lKKO9#_RQCwt61>43|lnca1dI4(q51|mAHVSB^%_Djbo0-f9- zJ3vJ5@qv1}_xkE7rxP@juS7g~_|P25${>&S*l*C1A9TNI)uhIf*7x^2c5s$ z7A=^EH89`f)Q}#!=uCRJkTKIlSFIWz{37_gaYXO-){gJDY5U9wFKn#jsF8#vS}oQf zhmKVwJfbgR^2^J{jZ!>0rKzcBptEnsgjd@uRfZxgN3XKd+bZa1Ms#%aW-{5}$HIaF zOiftbR)_woh3?$`3Q0!d55GT9{{TtUakB0AqIqTVd2DqD#@*Q?1@(-K(1L{3kT{Z+ z_gx+m!QLKm%1Upqkn^-zTI#SgE{`0;tzZ{?fWhz#b+8~dgBFwZ!XK~zXnCR2aCdMD zOBNS^^7dMNf(F3hHp=V!OQ)YZKD{%iG7R@w?2_g`i_Jcjd1b}3wYjKTq}8q8e_D{i zh4(alZQF?_O>f0vidNfopzHT?ut1sq$IfIr-wdO&YqbtzaLf0#Y`Jov=FmA-JuWEcK14wM zaXVYHS#F?qg2KRcE?7H=Gvi~1O>&G}=&+~D44YbTVYIK7}rkt{f~ z)7fLct7BH8nMt7alQ#@NED8q^K$HJzq?SF=QE^tTneE38WYV2WH1u~so%R@RDtoSd ztR`BLcAeKvh+shc8+S&Xq1AjMQfeHAOJ#}{BEcNB$#Ai*dIdLkJchIEvDduyqbZWy z14L$P;JsSvn-bByeQ4NLb(GmYb%y$@qay|7zJPt1Tr{5$dQfJcsi1cntAjjwSuVz<_8Y?2o@vYSIyU|s;v zVWskbiVf${0VXEyaDITES)uwKQBCsux94QDj*;!A>j$X$nf;`qloX+tM+8#&>0Pxl zDZ{*Ru#1BWkJITEZ2=uZzb6imX%}zE3DLu$H1@X4s|z6TW>+lP374@K%13)%CPx_m z$BxByT|V9wE`5+wv|yL6FkrH8V*eRj2He>BwaZBSSJl4m?1r*uiby5~^WU zTBb9@^V;Ir3KgX8iIp_(pi#J|g!Q>rGNW_d{*d;|kroe1g{v*?w&T|6h~@HoXGF|g z@zLz&=}-m(K`bQ_15~YZk9mpP6G%#}v7Q?WJ2dp_Vg~^K-WI;EqCz0K!@8YDR(%JJ z`EkqZ(l3B_mTcYjl)S+{pl&vY7W9}FulxXFnXEirRC-~SSUj2E*v*g~k?J;M$Xa zfbrm#etOLza_@Dd?(uZr4#paV^Fnw(Ez@US6z6WyeYcf^eSPFI3cZ%-SijYGJ#{&j z+RFM^qfj(@Q+dF}S-qpbHbP+Y^0Xdwo7n;SqsldN#^gPI+>I)uI9mwgA4AmU^B~^} z4$hO-(MHL7n(ZS2wgfwB2HEOsYcJ>JeN$KGWJIe>$m@I8VSFxnPYr~oEQ{sZoP@{6 zCGVTVa#~ExAbCLo!VD5tPe(;) zXTB);&l+RZrq(J90O>2Wf@AY&Zj!z~M^<W@7TJd z)u$2Qa&w#GFO?`KMC}09+vtO)?|C<=-k$+IBn-Hof3D+55#*ih&bS_wr9*@;Y3@et zsjPPYe2nKC1u2;l-XMJC&nm>KO-$(DzrAWqe^CPiTUvZBhj;&^i@kX4Nx#vgTUa4s zJDndzLtcHEwTus^JubuaI}Z)+*4pQsdw=vMHyuU!EN$U$XI0YKD&F9H$9A$h*)j#a zHsfVfI@(MDm!?dKIqSazGzcH>E`tP5c)U0>YtLiBHd7PhvTSy@@B8H;%heu*5`_rH+?Hgqzvz>=i7(lZDn-v%K(i;D|bYl5}^uM*xv<~DmU&|ohda?m7x>gY+dbm zco-oa9Fzpcf2d-lM2c0!jR`B;`+;^N5j^u&6VwzYVWxo?sD3+L-sZ-yu=d5&zCllvnU26OvP1d-mE2RYYV#9w<)5QGr`P|&ahzexc8 za-*t>Nn||Zi@vr&dfxQW>qOBHH-@Lhu_ur!D$XoMIz=YT2NYu+1q#Ics-)HnXhwsM zfDQSPlJdm*IJWGvlxXyTfST?rVQ4rM01vagq$Y~pTmSgg$U|WZ8gQ&^vj*{>t*~v% zJ!iF@-<;UILBrM5rR$_VTK3Z%WMh>@bSSY{`l;ahcJ!a!G_y#vP|sG zPp@rvE1sa)d_J}G%S{PA6yU4pwm3f;+p>#^=f#*kTGB@x-#=@Q(vm)9xo;^Gz%Hin z02!S7+6t#7G#5%Q zjtQflp><|n-hB5&2^0L0qr<~Rj<6*?O?;RBEy-&0CR|z(&H7|v3XJkqfhNH*NT-Jh zQ#3T^Z%tWf>cQ^$#6k)t20p%&2*S_I!SiRPvM>Lz7VXBU zfAMqxkBArK)D<%QMds|3g0}i}RlGY0K6f3oSiTY{8-ACYt?m0#m;DYS^TttIWNjx< z0r#!pt)mkRd^ftth=AXS%fYuzD|g4iKh5OB6WtCbV~0kPpFPO=K-G6P+$M9!lacgA zmr=1&N$OLMdtiEGU(VC(p+Ee7c5TGu&Xzi}2P(rq^~t2u@<;&N^1=k)$Q1N; z+pew=D2!v&CXCWgj|1^fy3@(2?(=!%{-53b875IVp;R;JI&-K=4^b|nJEmP&(X3m}J?yYJa* z+Nu7adC9!G`A+#NcUYR9U66+3&bQ+B;WFsxaO!FS1r=1jSyS&V2lu2BI2BTtajW68 zhb1>>%8S`fs^a4+v26LkMW5kQvgyR8<0=5kC)6yC-Lr&q@TF0h_E*v*No4b~bl@+7yUc+8u}AR}3H{ zbglAXP3<48&J(ZbO>JK` zDJOWE4C@;gBx-kjIwy$67o_7&(o}3{+9=oV2{2>8-7+qzvSxdIl5eZ9UBlIS{s?dW z-0H3HCp=Zy^kmlYKKf07H66kJwj32>*<-oLL<*QCm-T|B$29ZVd{u)tyFI#G%5rnf zb1Et1@NEyI@N55)wvBFzA^eU3f4Unyq++@||5l19du6MGybTp2`ev%#xsShZMxoBl z24bpcf4*pEs(4Ogw0kh}K-QgFC_1?&?}g5g-H|$K;m6LD`;@)He-m{yHB)UKuJvWl zY)(yWZ_jK%ObjVVm?EAU6N!v0x3e;j6$!(Ol9%j*u^}D1s+5Kv0D#o~9wk`=2lG@E zb<&)KW;9&w!};=f=SUMF74cNoiGfS>`IGC>)LiHsWY4Fbao2Uu&E5 z%wTJ|xvf5HTPBO;`l#d)>k94jP`;uaqR$^!*)WiY*BDvA6n<(X5Dc zr03tiGm%Aj=o-TkAhL-pAvDcGcgW5?&r*{^Kg!%ImbSok=x9r|%joAQfhqdF$A|h? zFJx($Yp}v5mks-5q7jIv(5yud!Dgx|STsm_VGbOK}z64=5 zVes;R!lobq!SqOpD(qmQ4APJ*h}_oY)I)nckJ;saC+3~}chzpa4x)VH0_B7fXKZb; zJI> zEiGr6J4s%tF1b&4crQ#8zTi0H8^wj$)cvK*j;Z!o;Qsb7`zId&uqXhqJ<6KWoHupnd^^+_BHj zMgMozr3@HBVm{E4V-DjT99G5mClyp zL;B-X8e@Yu^>O~{+iR7eyE56~>tpo`Ty#yRleLVirq|&r5qB6m-s)Hg!~?*@*RFW& zz$4cMIW4Fm=sc=4A|#}c5~E4%=*hK9@XGQfdb!P%s+V8GpZ4^Gm)`U&PL~{OZ;`=o zsXXe}J{01Y0fZ4nll<#m>o617drMp%h5g}a0J?7rrsrt@~^nKCsa!1b3&yCJR zD)6y?K1j;@mlfvt@Ly;rV0ej|dhAuS2t|IrW1=txyQ|gAQ>hpLi-2rgq5txb)OB3f zebsy*>a;&gvv|h2Y<%31H88r5LCecMA0NBsr8K$_%*^drelkj|O*BU^CrRbw822h)<7{7Hk0X(O5veX1=xG41I=;F|gV+$?ZDD|c z#WSt<_(fdX)4N~;J?I(U5k zRv4QOhZy+{v*3dwIujVVOitm5yZrZuAAo+RT@L4Sg39@7x~)q#Zp<9h&q3)NMi$hO zIB7Ye-w;wT{4uJcdU=}rGz?7;0R*)BE_9UJrMlc7f<9kUA0m)Bu|`3ZuZ%C7W$?bC z#7#>`86$qE^Y?h)w_|6W@YE)LfB5uuPoshbBAB`B!lM?=RnLL_^;<3$OK4bj9!mej z?@vPL=#&OY@a_JZq|cV8Wfxjg!GmZ=1xZW(e# zcwKHSnTde(;06ld??PXb0bH-d&bvqQ?6c@+MCFU`9~3hR;mC|fL7E zY?O|lV)|>2Aa*v;IrW~kInu72$URAW9f zV2@9VKGz;Tt;?-PN~$|S50F@{P^iOV_~#71$59|e-`UM+-mdY~b!-;HFtbyu`WXw+ zc76y7C&|@I4fb07e3bO{ZDNL^cKiV9`;yU6Kk90wx7IcIXVPr+R%~-V_lkE?XttGZ zG~=aAE1Gt7igu&5QYXQ14_VdVd2IVps+zl!r-w(@bg)epw=JQd+4f;}eTtQgI8tI< zPCLBJ@sY6@%zZS$y3JGG)qJgZQ&JJjaQ9FLiF93iJmIi+l4PQ4#pj1o$8(5qDE;D4N|^mj5r%4$zsKx( zZ0QZlNw$C=Yp)2PBhSgyen~>IJ~a+J)+1aO3hM+-;6#% zX+0fj>6|lQUH4w@`gq+GO(9=}6{HsqnR=+@GvNt%b3uRmEgV@m%7g;_&FDf^i9yzI znmFA1xVOIkC2g{9rEb!J<4Wl{@N5-kX=33E`k2*?gr@6}u|taahxVlHd_L$VLdW_J z^J%J+NInLb?Uew32|DXr+UMF0x1`-+>p|h)Mw)V!+ek~D=!NDt9#rsH4G)T72nkc1 zMoUTB+Q;TFfP2zBkX!F-SLscRl;y(?9LU%2`XCY>^5Ub_zi+p@ugt7weBnWjB(2is zOgGp)qO}*6{1IK4ZfizmEqn@B!5^I^cBzR9Ch!M?A?lT6?|QyUB&P#bdIuFPEiwn! zYbrt%CIBJyBGf?f4XXnF!w?=W{!bppw};cN2M?>^g}em}|GKj}LC$JvGdG(wQSEt4 ze)q$OO{g!zM%FpEE0p8c;o`b6LsjNEF*0jV0wiBh1AnNB?+mioeSFvsSx~+`UW`6ay@&GU)D#eSnyx-nG!NlkFVO z{JS=iZH_=5UqQ#{n=2Jl!YvtC8~yeUC5WjPpLX!a-Ko z*?cZPJ`8rgy$97QjvYvWc`9TaL#3r~@v-ASE5R~lLw%Q!lKF&W7HRtE5JKvoRsHO^2OG-N8C}VyuTfaYQK?VMq zq3WWP&zxYR58Dcs1K5hT%OQ4=MH!(5w^k`{E zqfRcU!!N7K!n`^!>4Hpu1_s#(hDsvaxVFjIBK@Ufq!qH#DXt7L)6^?8<&J{?W8cBX zwG&Xv_dS$elW^paOKqgOrN)m+Z=i-Q;o(zHim7H;a$@7@m5C;KgL5K0Y=}r0S16bj(^rTCsEb;xRDT;*YRoL$R%BG@X%%Dide0Z{(e*={h|H4m-Fic@AX~&lW>iO&trSJ zv|In&+2msWWp97beq`X0%gce`g%_vEF2p?9{qD3jpy4fr_s)?Ye}>-Sr-J)UYUj<) zENDLZW#;QGh#~&g#As=Ja=d8y%yKK-KzsC|wlJc>t!7?a^xHEf97r|q8HurIh-I#u zn=|S5um;7)VJi!akDuJ~sNjg-*-IhOON(Gw`da@Zy7V(0z)#wXxlg z#QH+392Pz7UiNW&C)aDWsm+Z%P%LgEk=UfQ>kn+L+*zc6@6&a{*-Y&0%$%H!b#+x$ zOoHzG?DvulB9|r6#KZp$saP=T9bzh-4vmm0R*|}o5QkT@ZdIRLlsa4j9-JZbgXIWo zkEd8;Z}*vJ-X<&8j}helZeMdFqRGGUY!6PGMp)B48F)v2yBYLb6klO>I!t4YR=)E1 zIVS0D@BNZIA`gMuJ>KrteS)|<3slOsww^#<6iq)Sx3-u)Mu*r9njL-kq>P{u8C?1- zS)6{kb-a;9A$vb!JusKpPu4~wSIF;)T9Q>|*ZWGzoi6ZlN(_oBe&Ju?n`Nf!4AXUtl(uqXp2ioSA{Q)(&;bf6V|W{(k!;?V?K$2%sLrlCwy62JYfxsI~}#h-2uH+K&jJja4Z30%Oo8MJTXJ8wqA zrb zXOm(E#dXhx8o$0j>48BB+4fE8h6DyChx~}D1C5`gs65__`r!>=_*<;H5Gd&0+D^`R zG*TpMm3o3*-+AJ!YO@vbdwP&hG4%-2d+*iWyQflm0m9e6c}DK|G@W-RFTR6sQ*z@R zvkXvv-nIj%01^GzyU<-ZRAPCnKT>i=9^?#RaLXeknzwK{9 zaJ?3!eJTZb4swbF^Tr!z2@lmR>joEQX`RD;@z%{8C~B^4+3%Cdf2>&etGD?|q(u;% zTy;n5pW5Ci6N3u7 zmqx_k7Lh~Iz-JmRxog3u?LHw9!0N;0A?fEiSsT*~pQlPw^9;4ov&VJ(D|OqTWO#F( z=N3qpuAE@{t8txMY_6D-^<-Jm0EQ>r0}m4}8XDu8^EBPQvR%Q-KQu$!y*U2f>(uVu z5b9*0tbSRfEq7%htNvW3=OC^eN6!_B;j1zR`-rL*)X=HRFq|8Uu(AIMWjZ+C$T7 zCMtil?EW)bZI#;YR;!0m(4f+ODWnAxBMS0pZ9IK*c^Qa)ONoy|qma8<`bcmmDQ*0H z!sb?;Q$T-~_8h<1I2Y}yzTAmF`}#3%;N?;9)wKUU9}UAr%od86A#-^e394;M5)q=e z(Da}Ohpg``a1r!1d4Qi&=c%K-!D@P0(sDj~WPXSK!B8jUAvGcY4nB8olu$5Uy4GQ3grc6i+@E0M4 z^1mkdvhkYnm!Q`j=!Z7V`+iP|;Q8w>oM6Rw-IK3G=a2egN-hS4m+*Tb?E@SS4_6!8 zGN3CIr%Gd?83lkTiWqQD$A6;u*QYgoTgs*m;GZ3QwnrWISfyP!@QOOF+va^Z`mkT< z08nU63U381#|2%X@E4|XTWJHQSs{%3+^*N+i9YJ*e$2Zp)C6J(8t9_@!oTN5q_Eyk zcQHSP4j+J|3c4s<5#MQ`fBzT2sZDR>k`4`knIk@@TMZfN0UA<11MB+uNgMV8O4)~0?O+82F3{U#kvG;e?e-soa0z1`&s+OfE$j5m*88w4zQ z+CM`7VsM<&dIfQPI#w&2>$?if2C4a(gafRi*IiJ?o-X6}^hNiEGmaXGZ~Jqi1^^oZ zmh+!{Z?Uu3bmM*#rlC9^CU>hoaa=V@t(`!YS2N!fU4xQYJqgVT^%}OU(ufA`k8xoD zfWOZ7-7_}CG|MO_u8^bXWwcKGLPefA%SE@b3p>xWTt{HX%C2-w1Kz^(+zj9d9=B%c zgz{{KWi2x2WMoD8jIB3FX5?}}3UP3Al&@V!*zIh=`Dqap3(jmfcRF{j?((0isr&yJ zd+VsSqOV(&3PlQ(;!c6$R@}9?yGwC*D-OlIxO;)3K?)R2ad!#s?(QM)@cpj5G46NY zc=;z8N0KcoYt1$1+WUMw=LrK*Zdt+G(6dp?(hk+4bm0|r(b+lub7+(yv4NXxkhRCw zyBx`od%o`8!mXpiegfZ}YhC>@Cw!$uX180WK z?z!DDU^d3El;;FBqTj{#Z;|5JrYoyu9JW$Cy}H}!h<7-6^KX;8-bNS~v{3Kr#@n-e zzc{Fd3>V@;UzjHX4~HE35Wz5%OagC-`1qwa>p&`AjY*(AIc%vj9oG^L~3!&Yf z5|izl*8zPHSdIFsidC2ATg0#HQF%5gZP~|?K@Z7XjTVig7NdsMtZdJ>7wT}oRT!>; z3M-nfXZ5)lbe7p7;sm;1Dm82A~9$~*);5D67oRnq|zN9nORFvriH}?KVf2FNUqgN?B&((Wp8t>iF_UUL7 zZA}w@Y&#qxzv7V1HHE58L$b}&cM-a$MSb4PjQ+3EW&6e&-Je>wOigjV_>Byl+sMc_ zqGUARZ%mJHWDa={*W$UUag|l@$lQ`#y5Gh5XcGN*%;TrpHw+WoO#R&#ceRe>}9a z$hw2wCajH}X;tMnaxp9FbGIopg0xcH9E9jkMpr{=X=zL0zHN=ekuy6H^?i}scF+@3 z-r^pe>@2X%(?EP9ffy3Zf8~CgG-T@OX(dG~gA5 zFy5Qj{}6w|;i1&5UiOlSpv&<8ggu}T&uNa;zzo_S4r-?T>CL*7@I=<&Mbyqx|LTn(1RaI@$yP5ppWb}(N(paC=u+0E8wSVQ+_9?R9 zY@^2tOZ=56J2ashs3eWuyqxxg2PJ%buM-a!0f&hEFyy!nM#T2^w{v%oC97aKe{O|z zqw`?*s<1{}VfRh8J<{T~rUq|nrI_&u_(&5p485(J(rW)|6QE%fdTU+3RSn2&<2 z5d$aVo=iA?APV20q@}dK!;(;e-TOs%Ute9a@Y}bdKS4&fr0vsSmc*Zc|#W<$dC znCdAyFrk|hzKV!nac}NyMMb6eh{bE@M_fE-Bh?sA zy{U1hDBt&EIpo+mII!;_psewu>K&)BA9cw#O%f9{RRO?4*!aB}+eexsnDpq%&?~!Bh6l|%SlH!dDKVVh znRL%s;-6ngM1CU}(wIUoQN`+6cf=1}cbt2YXmg}x8e+BD*ut54^iho3c6P3s+%ug} zO)T+UD{2ia0h94RE3fii9^yBS%#)xo^FU>z4t!Nu+v^y*lKIX~Zl^h%r~Y7{d}qmD zs{kKDAr^1!o@+R1ipn7(>HjL(D7dv}VrU3nqqf&n^?uT1Ga;V*`Lir#;L(1Cjh&U9 z6ZCKU+*7ZL{cBbNos7JkoOF1pVZ0p#5JUT=bagYwcF8W@Q2xYyQpW1py|k%Me@HMQ z2{BBe%y1*fF9*6_Nr7%zdOjT;6C)L5L|PU5fSxOXIPrVBz*v=3KwsbOnxAB7uvCh( zRgp8|^JA^Qc5Ubn=$sMRY8*n?hMLvVsqMIkMA=?@c~XWsM+ulFG67sa`t8&S8Rz%k z4(Q|W%R69550*yThEo}Im12Pz<00axBB<<5Jor#Dm7#oa!_TBBAJeC4J>_8&dbd zop|o_+qEsB?Hk1vA&zU}zUk%W?fJAHbvQXcOZfhIX{#?kfIYmNe3<+e7rE}4K7I)K z!Iz%1Hhn8ACr4olC3T2}&BV4GU*GTSeBklt=Z}mSbv{fJQ{>5RT7BjO z>U4Mn`1l8hhc?#MSlk;$V!lgxR|Wi>KA(asEEDxAL)}gk`G#r%tNDykqm{rj^0Q$2 z{=i32u|dR5M<;`ZF(w~Bl3cGUgFun-@b`tkZ@f$qMg%(rg#aZbB@bnCzLj<^xvW-% zmgp3_JR5@%en#J z&eWlGXHWhdg4C|L@wbRedn=}_(O(o!o+OH;)pXvom^poZ;$ zpH#@HzV@3R&fb3&OAs$0j0@IO@k~qiXS*g4*@- z?+l4e55BWI81rmTo^ImU_a8-NM7JanX=D52&{f`%3yDfyrc_R7tABQ+hGp5Fe7os0 zBti=t+kGD*8lfg5Yc&r^%*Y^!D=AJnjtE0uMA?okkZs$#EoM-jNT{IPYouQ{RlG+c zdkZUp%Zna7AGs@Z5Y2BJdKIZ#x>|+-AT>Cwu(c1sTOQH#O~OYF)T(=TNIpV>&m;%0gC_|F z2@VFyjiWvvYLJ1hVQ5HjSV*hqg(9J?8)D?psXl^#u*uGz<@J6CG>)AtxSF=(c15F% z%I7xCkW?Qkm(s&RNPx>6L;wGIN-rT^f zRwDD4()mBPS*U`etv*w)p7q*Ks|-mWWeS*>Z>%Bz8bqKP&=OGYuCl}4Gk41PDW@kp zLG`r14(aVf!}Vbcnt?M%3RUpWEldhRHIS8RA%IU^G*8vJ1gDzl%)vr)f~DS3RGe=5 zI=AT!6nBJ$OYfQOm#kw53EPo;e)eOCvgW)K1kHK}zbE#Ay^%-EH(d4pX?whvmz@BK zF%~=~)EhIgxr@t`ki5ICfcSgAl}9v66h#{*Ia>K;MC_f)8I+nE)&J?&(W)F=00xuA z+3wz6wZj9cxB%nniW?cT$Q-_oWF*NQZCu%*Z96AeGZ z)=2qUW{U)#VJ63=rCe;mKI9R{Hqvg}gZHi@L|-+t`|Z-BO0NWN**rIgioe&X69L(z z<}K+ym$UuMFZ-(?1SAF{!DTRPzAPe$mU@h^hs9yB(rJ2LmD$WA9gWY0s?{J>A^C4` zgdnfg)()sLCF}1s!(M+@GxJW|@|Bt%nmrYq@IXqRiJ_!qn48U$*Ub@&!%Az8fOm!N zW-8wWMKJpHyF`zw!*Xx`uD6P*?-WM7qhY(Yf29;&`n(48xykiJU*MEB+xp;wV}w{z ze$V>+(r(mdjbox~K{y*^u~^vVEAw5;w&6?M#v#O(tKBe$n(K$E^YoDFuFE~aYk9YJ z_nwDkbA^*{Dzg%}*6gmesr)EjWcfmG;VsxL_4KtGrL!S{AH;`m*Zx65W97@7>n@(X z3Te7DNSKf;6a_wFihdqb%#Lt7Sm{mrx_7&Ky9#3Q8HGb|VazFR8v3nlhryivAwDH2 z6A4bKpmaN(E(-Pl;Y5k(Gyn|kG;TL~vu z9ao2X$DMTV_80;o9v8Cudj>AwNOYrRIWl z98qFW#Kr`vYrDhAgU4BNodvt0*qCnLN1qU8%iW(gO-n%o5zBnPMzlF0E>bacCxse+ z9@*X_e8?UH|0&zd9It3dW{-TU!eh_Sx0Em4Qy=&Wh7YdTUJ{N%FDv-^H73zR z;b+)}mkFU|e~WU4eDj}OMSdrfUv~@G4cDx=WMsjP(Q+|=G9C@)=hz^hk0#yNUct$L z_<=s50)4um5TbgR8!n1ReekfhwlnLLMdSfL>IJ(C5Wc5-n7eA7{CMBtFogVg;SF(; zHr6n=N4-T;e{QtfZhBx_&_EYhX}`ImE{@IW)OPaXEiA4oD(Xq}^L4V{KA~0#(%`v} zIFp?hwe}1&vH> zB}S!us$O-Q*oIV{Pyq7W*S4c}b+ss0X}|_?u``Wq_N=7R4}1KJI5;r!7LKNgCJvPp zk&J%fGw#iBP+06%`bu9NB$pF;EiChu=2o0Oz0yPW{fX*)5oEV1spL8oxz)kn&*T+c z-qz4L2nwK(f!wR7`2{Up`4+fHJWLOxOOZ15+#U596MH)?x4=a&`K}ABdm#SypCfeS zR?2^Dc$2s17)?aXfy;O#@aV?RQtPn!cxoycLd67JmGlNo`t&MEizp~`#qY6AeHjIa z`WSm3Zf=03$8Z6Y?>b0d0zc1>zILSyHBdx+@dXexpH?FN*1%n8Ys-g+YZV@72z#C{ z!qVswJ4lmQJ32bb>_w4gek)U`bG^zl-NfU-zZ|1mwZBGH&B@hbwLaRBEDhyRO^8s~ zjNtPawR8{%^9cB_RmUi*&}R2yavkfB7j#~c(w4QO)A%doa2J2yId7jLUj@e}zItg* z(tD!vQQz{_^qrl@&&&3M@v6^>C!8zGpCn}p#h1X1iaW5yr6;)6$NnD1&DUA5i97E{ z)8`!29YQqoVg}SAbzep$H2DYb2J(5DNP<&7c|Vf3{s2f}`f}QO%Rqd@{@$B&Vib|#i$+{DjL-WR)muzc%JkoqK4 zw&{pqzbClbZi3cYB)`bCP-kQsRp#Y$lWlm(n|LCVOMJg!70-q{bB82PX`^(>CKvh)e$j_;*^PR(Rr-ROI(o%>?3{sFVCh#arORZ3ak`PCgs#*b>qqS z9gV&9&1RgTni~aNUbixcWzYZ78y@xcj_b1k22 za^?F%+}aSM7=~>ZL5gQT_cI^~#u$rpw%lDMcB8+*FPw>)vUwZ2jbx!wf7SPoBhOGKh(a z0((I^1K)|mfvf9mo@H-`A8JG%c*n0;OIrnlo*drQa#WI!zLG^p+o7?Yr;Xt#Z^SS zzhimWIsUi9q!1DbL%!=hV)s(c*|*>t9Xv%B4xClEqG_m||5ew1yt9mf8SB?rzv~}; zkBKmB-NG~*`p6`9Futhov;OT%$^F&H`-My=#LSC}?u8les*vu;`f~O|*zKQJZf?l; zd{}Tv?1uA`=+r0VYT)u?_;3GZ)AtE!qRRg`6;Z0vbY1GR5oxqibn z+(O@ZX-=a<6m>9zN_SS_$~bI|PZ&{g1@^!1Wj(r143ubdN42)?Ap4~g7I=Ic(|#ki zRNK^CmRYW+p@FHk{5Bv#;knOLqENT{`;X+B$&5GKIzCGlJzv|FlCYj4x>X{ADdMXK z3XFBPF#;+2#R1|1aoxEI$a?et>Y>R`1w%0&#h<+DEH+29@9##D$Wwl&f~vq9bAQx$ zyz}Yo`qcFlA}Ymsu#=1UG*X_yG?h3->Q{w0r^c1y(jA5}p;rqC(#{!w@q&an*SE^B zsiVqWX@aywX}+3#b?bYk=KPMA0W)?qV7t5TOuJ+MElb@7DtmdOFZHlp!(61E|MgZQ`QMHp~ zWyR;oN=%|gpD>ANa`({d!!lH)0VOqVO1hI}ul;0c_}%^XZklV>VQP)ha;u*o3kGp{ zs2z-8egq}{B}#lzGt#^qGGuw@Z$o`;rk!Gh7i#nwLs~{AQi~yHX_1nVkx@WEfa2w~ zDW#;=zUva*jCN_6=;}L>MIEnq8T-a-7>_)s`lQ3c_=x3CUDqz`IR}TJ+bPv?{CuYUJ`FCJumHeyz|>2a2=t=w$wn)1*!a0 zyA9e9ZN81KDvxB-&TJ)JZ;sa8nLM(r)O6`)2V?O92M4lX2WV>PYV%xvj6ys(oE$CJ zb7v>f#S6P{xLCg))Q7w3hc$+gK;rcX7SdD2dx_`u$V=oR9lM=i{3qJl&blXnbZ|a! zs>mu#idE9gz)MWS-(@w#+z3wzL=!&`=EawGDj2qP?YsraRjny%N*ZRI(Y~tl8_Eks zB`j-3%0u5C2CFJC%9JCfs&>-T+26rbjBS*4#0N`@v`8Mk~FmRmzvExHV>da-50Meb)@BEQRo&=;ZM-mZ9c|L)CICMPJUT8%Z@! zm#t3<+<9%SO)bxAeLHgTM5UITV0Fz?7VF!JnZYzNmU`t zo#pd@QJlSlU-&!;+(lj@k#J7!g(<#_AY}!wE`JB<*HxHTrqO(EM=m>5<0{6rlv_Vx z{<81OQBXeu&t|(Jt~J0aoGxOtGiw5({dlE~Xd{Lw;yPr%dWPp*)@#&demc(L=0vcr zF`OASucDJ20_RL)M~DPRNt3d6+Mfa9Q8{_IL|V5{j1ba1^oS}!Az-)Z3x(o7h*ua^ zI^YsM>`$cbL4x?Dewec#Wd1#v0axC`TQI%l^wVtAF{v_DdUzAtzC2kKe*3C;wZh#c z?OM3A{-Wv5G#wLUDT@HWpept%^C7BWanorB*x1HE3w3=JiLcwh!0mpSJ!TRg|L!)K zG-(t+kcm6m$f4ZjI8M^v$`x-=R|r`ZLE9qWy_ zXkD!xbQ3H+jY)g%2w5#%B#wctbn1y3jG-u8$)^mW__sQL{>*NV&SVN~H8b3wjxUY& zd65b($zE3L6jCbQVEd-Mhl4B2J8&QjU=7r@d%8X?O;5;Sbepu_nkXvE>W>SzXMVDI za4C_G6Kdt*OQ^G1+Y^|$m-AI2(ZC|U7MGbq>H5M>5fk$eEb#Fa+#rBdm1cj15fee0 z8%p!7DmhihBw$$xIV7G|J$Wgd*wOM81n!wm2W@HSqQAy)IcBlwv zLKIR7{(j<8IVaDCzw0zlZEJErJ7&bh8iAk@+O!+qVR5~G&eA6bMe{89ES*UUbrHt= zR6MUzy*y{r{>9=NPl`|UWf;9ZBjd_8 zf`S?Lge=vz?tiAc7^pA5EuU*y< ziLLjQ3n=HmFUa>wmpny7Msg#d&Z97_#>YI)=J_tFoT=KMzd(`?`{rhtMa3A5`426O z+2tH*USG>fd!*$R)UQ>%TfM5}!3Nw!c$p~=>j!~DR`R;WPOfnO83|fjQJ>dlw&rx+ zCgquF_)p)XqE>UVW`;^rLh@skeot9GC!)mDd^M<6pL=4J+cJWc7v~trb8PPx{(1YF zTxQ@m@5b<=RxOyD5;`OZYK5FVfF#;S6iJ9uEs+ZrL2~}q6T0HTELLU#anc{r= z?Bl+DSAey~%aF)5mhO8?GN9^Cygh6KLay`6$giu}FAh+-LNZ)FmRi+#%-XfmL{%Zu z;}lKs+r1HZrAXxM-xmorns52TEkX6}JnoHQk!g?r#pSM~tM~3RO{!tBSN~SdS^i3Q zU6}U2(BxMvR?_(}UAHsYIzeJawPz>OL{j^wq5J|)L;aH4y4%s8?4q9oRjq$3r%ziy z`zoq9vH*jUQ2Mm^E>FtICT69%L3__sa%ga5rS`Cd<6O}JTsOK7n$LOI##dA4|)FHBz1#OwCp&1;%(w*PM8iQvZsvWfbiFz zF477Kk%>8bl*NqJ9xb*gKM1({@5NhWepeV0O-R|6!kQ&+zV02bY+|)oTwxsRjEpF= z$b?I>otwi=5=ZI+e|&m{MPSCiH{B@Gqt4sd+Z}L<8C8DeQ|i@#BphLG#zFS_oHPj= zn1-Z@$w?JA%)w9eGL#z+(&&xV8!0~Emmp*!!@myvmv>lowl+M#(hhG%)1>YuKT0QU@j`mh3LbSDq(OP zY}eyZ_YmprYvMA`s<+Wa_pgN>7_T4e&()id^>Klbo)A7mD8e9i+Fz2*6v5=v{AiuQnYlNmAZ13f z-ZHwtQr;MxZnN=`DtKvqt+s^yGdV zIoLj}gC(;kNd1qj)I^(k3%R!TnFglC8bZCTFtg6csm)FYai4J6l0ci1vuPY+*LvV!0Wg z^vHsZwV{{pVPtdX@O(S)J3*|#pd9H7=Na7^pt3^jnevF-a96S0+8OPP3o1p91(mklDngOn}jE4ZtRwd<`uJ1udcqggVC));Oxa& zGbnDJ7~m&*45h>L4OKn1JwJcNpP?shW{2DQIz~#9>QR%DBYDO(=dD+xfdm)}Tv>wT zS(uaG%SSWp6fb~S{EsLIyeCm0KEE6v{P@=YLap3LzcREQ!{Ft~Lo^6Kz^_|!u3h1Mgj}cd_f%hkSH3W@o4CPS_?? zVUq)V`#=LKZEb9f%~Vyvwfg!lbvhi;?Y-SYKZJ6Q4HLbl$7jD-^ADEz_V%!S=)Twd zS2|tjKXnF0$dN{j=NEL``x^DUOuuFV?6D}0uu2CP@~>O0&y-((FOLEp@$KutDgY5B zfecl&MG=d7cRzNjt8QL;2CJxU0=230(nOeSCiB!W4#s7vSKCpo_#{cvsjp59V~@b8 zIqn{?nzy%p#4*2(!3-~EaWS`Y4CwOPjc*1^I#xDiAnreiR9#e2HFGUW!ZMyQ63n)e z(?^~XBjO?~!pTz6rS)uoj04M6DGalaEcbqg-fg`ZgbqfDM<6#SyifbrvhfO ztw#dzqNdfi+?2pq=L2?J+Kd#^TRJ{dzFmer^<;7Qh7YK-nrai$)bnEgeUx;4+!|AWXat!lXa>gLGXp6?t$ z;2_y1ekw%<+B1Zc^+5(DvY>W{A(!7t?i{o4QGq@O2b)bH#7`HkWF&{9(`o^s#;?*` zfO;6;bb!n`^fXcw2wW!$J4I!lzzaCxwA3`){fByVYTMq8b%T%Jl?lXuYmX*pV7^&jC zSLieaS|5$UjIB=qcagvQA!(>ZOSX^KUnv^kfyZDTJOTpxGpK;m36KL2&R?mbtB@$o z!h!;j0XT$b2`~-Hw?0F0u?_yKv4%4a_t%nH!AlST|2Bq|irh6rKyzRSnAd{}(?A-5Yq1-GG2BypAAr z7k_J_ZuVnvF(4Ospw}?+$vvTwg$oB{MLkI)%>NWN6`Bh{5~pT-S~|ey8-)kMMp?>q zK;pUaUEW-*>rQlNJa^xu&Sz2l2aBu{PnKH__YN!+cl z-mm+ZzIM4`k<)j}oNdKyhEooWp3|gjqyy*=%T#d^P+W)Xt#utpL;lw=mctXDcsrdj zst}?yfw?y6F5Vj^yLZe&xbfx8EFK&+%sIX42VbfaD{H6>zp2z&o$?U+WO?%Z-wGTw zW)oh?LQAflKn}X#_QN$wO%p3oL}@{mT9NAvP7dq&MIMi91Gi1K>~iCq$DrfH=0;0n zRY;Lrt`*-8FiQwn66ii0<&?u)f1;_IHr?)Q-U}(5f6_UmeApAey-Q?j3qF4s6{rw6 zR8l%CvTK_Q!Zas}HAlqsb)D=VG1O(`aXQoFwQ8jK?Gr*}^iH z5b}rjo|klYJ5?WhA?73e1c`-~57+JRnZ~;J*=T-_Mv!SLmRGm!-(1Onh9_Zz+17(5 z?Pf~^yr28Cu|&gZ&c@TbaRe6eEMgVa%I6^-Qg2L9QMX~Bqz~?BF-zd5yQ)x;@FIf3@G3w^)cIuF}1_ZoP&$x3~7V22d4kL7DvdQDR zwZyfobO^%kLBx??-ZS=ogX1h?&&V!s6jFCQu_8#x&%mjhCV75s(?GZi>P;l8>K@BYCHEc14+Otu6e4%~LPc<6=bgBz~wdH>a|6R~U?-aAMwOO#gp<3m1lS7ra zsn2$!Bmo0;;KIreZAAv`1lK3#+-rM1cQ}==*IK|3zPT%i8M$;*ogxJ0qf_&8bavR;Y}1~N$G_xG%aL`7s`#wb*1M=%neceW0S7MX=&?-I!KwNuUr>g9~X6&hrk zX5LlkG0gulHjNXD6>$qw@JBr|FOND?6v5JPQAYnyTvwI2UlrW=P3UH8>;R%wC$&AS zkVGU)K-m4-`awXe;MUYhGj4wIu_430uvOjBsfEI9T)>5}XOl=i#JWk;ympnj8-TGm%y;b?`-Zgj`MPpdHU@i+EK zA!6dg^KfU!*WF9z%7gGTMV1QVavll^Q^D*7&mP`;S+bcCtFC+=EMZ z8iaOzP`$eH`<=wN3Tus^=pebh*Br1(VPnHa%*=fvez*yJaXyCU;enE=xgp zbvix0Fc_SQ?(BElgm~=5iKCa0mK>(r)%GBsFd>fI0|E@0QKG?d(0v?SFTL8+bS`Hb$)+0cAKF(8e5BVv_aEtTRW_n5y&=IrJA*CX`b;U z85{Cv#Iv7SnUWODW^0GWsgMjac{bsY>~I`Ru(?8IPPfMjr$RJP`IvK7dVaTh zsEWjIre$PW|9#-+6PUh&c;LPk0A|QM62YH z-gC+SpusmadYE(ODe}J1A|No#$ z;4OZLM!wWIP{Acx0wUfS%PUH{73vH;Bea)qi0wbTSDi6#)q49PtK_9^5k8e#zhSa{ zda0gJ@&O8Qu$F#d=lz4eppd++e`!KAB4q%xrqQJ{Q%Mu#2o!dFdJo_pZNQu>4W=ai z=Rskh?jq?EqEaN1J%E`_I{>Ux3)EfwZbmZ0d^ysexBDTl8sqks)s3j;UrBab5kM*GSwFI}`<@bFLqBKX7;*`vKbyhx|85(|_;3RY5>gX_AZA;vyEtWm>Lx z6z`ZA>SV@R-&*aZXL@bM3c#|`5-!XxV8QR?EfUGRI5i zfP0_srg1%_OS8*=v1jq`FnM)rA*lnqlvQe*d6#np9cW7&aI~hOOfD(krYM za^&YU4?m`bV~?Z+LF9opuuU02EI9nx+9ve_)z;`PS}S4oa1b~f=&@JQ@5&79u`BfW zxmdXU&hLXYF%&h&j5XZ%^0h8_$@xxsA4c9tTxeAM4{vzKx|)()&vE_Y4yVDc7YfZs zc^Phox%M+51QPQ6ONK{FR`S%ORb12OJK9UkQ6^?n+yJ2T~H~bZUjP1pN zKxe-9FeTdd8o-EuVIe;!#NDzrWL`_jAjS)(n~ZJpF?}dRB1`aAwNC#aNdItM!whwn zrpQ0+E;3Ni@FMt;6DD?ayT(YNXOoUNT_0`JnEsuHLI3+T9vs&ij|!Zj{!Y;T8PJVm)w8=Tn3FFGQ59hu{|1T z6@nOR@I9X6W~O>k|KTeqhWsuNLN`w{kIjzYSD(u};7J%FECthrZ5vOI9(n{2v&XKv zt-G*8;vioy2E;+73OCo^hO2?p@)qyJsKwxiSz26aw8;7LcHMYm%(O!lB3k*Up00kb zKP#gs-_AW+rWaOERXLyxnJ?W`4i2zo5)JPbE{hC2LkNXlJbB86JY2Ko+PG8_ zOiy`Uvj0L?W}qp!8kLpuZ=dxxH_aW9UBFX1;1tZ^9_yh|NPvWU=&e>;Q?{$K(~1$h{H{^RicvPZ1Ig=Kpou$!<~ z5n0%WR!i3FZei~?k$8W{bdKs9mqBBdG;S1pW1fYLi#gzQ_ExY#J8qs9=flX#G1thW zq00~vsHc*HLyA2aU34#L3yXXj=P4YCHn8Dmgd9eVSl)(FtXZtBtImL*aOvWylr7jW zk^RVrS^Vz#dru|n+1_Fxe3Ixs2T{XwXZ1C>*qK4nFq$~~UUbC0w{1?yftl>rKSDlG zc-bqOLh^os7s{)jrU8IFWoARj^i?adTz?<_Rz0TNls=~FH{tdf_^Qp!fJ6=2u!&UP ztIlH~^769s9xvd@o}^U-C5;Ar56N+0sbM)^NTw$=?bYNTqQh>g1u-f2=j;P}1>@l1 zBz`Ui&}XLG^XN}K%p{ryy{Dp*GI!|04KTThv`24BNJLq}li9VhXm`0Q-$tIfXi ziXa|wMB?*3X_c5!PJ)m&avG&TUq66Y9JG@D*w4M73xdS!6~6g?y(5H@V^Xq&zj5L4 zLM|57zs*bP1jt1c@kS3-hof0`&%J}LWS=UH4M%N=`G$fY^>_VSc80xmMo2SEY8N$1 z0t9L{&P(JWhCV&C&xkbWYPe2m2vlmq*xW#u1Y>lxjj3ZR&_F9;L?bpaD-^}A zG*}l!P8}^46)p5E`*Mh6M7|Vn4xmv#KNqJnQ3IVa0%xuGF%)j57~lwbv+hHNvJYWn z$2)bDG2del(5jYgXQG2fAg)}VFz`Mslt=Mc7vZpFYu)@`vN5CKXAJDD(qDVkhc*XQ z{Bfp96+^nVTJAE-L> z_|MaNHkxIWtt*k8;duF-obFzgFtFHz%(@{F?XJ&T(T(NSe1zbdXtHIZ&=Dw?y$MgA zI*mEe?_$<2H14veSm0V00;n5NeD`#ABiLD0aXGk7f!=VXpIVnB?L%0D{`84kZK0na zuzgIkYTS_m2}fJ{{ik?^g)I-r4_|E>tJ~sGOXC_+x1OeeGoVPC8>8whni4pPnp9BE|V`@CTr}K-*2%FMsi3 zwJGvq^Jb*nUrW>~?M#_&9dJJZa-P6rrNDQMn#^U#%Xjk76{7)gK>!kI&#yJYp^g7y zRWQ%}VvrBuX-JT7pOPtCspva@(MSHG8Fantxmp)j!9o|sN;`W6E(suvia3OGF8wxa z7@%Sk_3C|!)ZLi zHnEG@E(pn*wRo2^C-YJoXF2jI_bI@)DP+N zDzVLO6Tmt|1ghRXik=}*N|olM=Gkx7*|ndeff`6uSFcu@3)Dg&f<{Gdh#u5i0$s#$D786kmCy_-Wc7| zp)*c=#jbJ~$D9a_5IrU)apJjaeo*YoBCEH}fa232l;@Tyg$iW>v=|0$*+ z(9CdnfrFGlwZo6347iXN%^E+k#*ld=?fZnE+*q)GudN?riY{E=^paYa+j2|NG{dR_ zTGFES9ktBJi)C*Bi<@LpR9Kh;O#n6*#(kzP({L9TyCh_OG_rHZ$*5gtQn8gw7Ij+G zPoFQU2};R7EWSq&FERZkCd3DJ-wIxi7oY4&jZ<*~Ai6Np3-zDzUli?C!z{L2NP3;` zR4(W`2Y=q;GJ*455&%4RJa@d?sB@!+{0o>$M8S+W{RSqae@ap`g`lQfr114$ATo${bsj&PA^LGJ7eJ zzsdZwdYAnTW7K1#w<^I7v+Hzk;@XL|gz=LMx{MB)QFLK8bbZcOJ#!Q3%+t0OOHquG zHz^r_Nol`EOfNa$6vkH<>&P{ZS4vkOWd=(PNR+IK4A)h}{b_9anLFo_iYkB;(fe(YKz&v6cqtx6T4Z8(U-{+a-FOr;!_X%} z!jCl)qsnmAwHX0%NHp<)qEt1Gc)7I+jXpLPNWc*NrMNS9c^5m>WholIwUVT>6Eqfy zXtZ+QWZAg-aSTIrFIAQRNuQeO+PQXe3jK=zvoRRK0e@X*NGz|)Os{36`>Rotm*@p` z1UJuoTWDZ$v0t(|g?roGx$nKN2d;c%0XI?3zu|_d=sIN;QK{bZSE$ACMOnnA|MF?v zaKRpOIrA6YK6emxh>`TH0kZ3ykixL_D?hDs3M)T2&?dm+9=0lHyS~o;<8^`Uwil*37hDWP}3*F_49QJ~4P>KK5 z)HqiAb!$xL>mALV#hAm>48_c&tEYp?&r~-rFwcJE`U20O&jqi=^>0w=yRdQ42ita| z$J+;|5rz;S5z5>2x)y38feWep04W0JyMIwss+wqjxW>^n+;i*a%2i@-R1PHEb1o$o zm-+nJq*vgvvSL{GH)c4W*K+=$h=$*Fth^!BN4Tl@N2^DMT#pZopRgO&dpT|mMqQ2X zj@Rx_+2wJE%^tR=8hm?$ZGUw&N!8u#w8=o^+{HM>wd+T&uBNUF^(-lRG7@#ivx+q} z=g5`jL*2dIHkwtoKk@Z17|PX#i71$n=h@oZe8mM&Incs%orXCk8t+a$u}Z&j0xCk1 zpErmJU-DK@kCkA)Q#{pb?-!aAhUmKuH3tWC7xk`OcV-?#kOL1A!UE|EIF+j%sT8*72eO z0s;b3CDKt8q!%gDQRy8*5x59Q6GD+1<!=r;ts-jT(Lt~WXpMCz- z%TY$IPcAnoFPa=Dci>&AK6~Y*vCe>Y7Q{&w?auk4{biPF4cxsK zh%rA(&Xjou&%uXA%`yiT1)P=0oK+m|qJ3pl55ugYQi~K{Ui6A#RSiNb$oRtqzCVMf zc_aMYHq~LVg6GMc_uCq)&2jK3>DA$vgdsB8p{~yhPAQId)_9B!w*}-)4rp|WeD6@*Ve;4bqG@!U;W(5%dWfS-Asp#rEMSm`0oFOFK=ZgZ~X zh)wv!Mi$IEY4eL1>4}_E4a;Ecn_LlH-oj`7OcmMh)o5|+&V*^IKRvE)O81ptzwx`m za6*NU0Qc;abGkiGJJpavu;OI?%bD>ah-Xfy4uLoh9|s7gAJobHEwzjyRZzN|LWi0N zS!{6i`etvD-eY(Qh2;vSx*AcK>6sOgd6KLNSZ+ItBI~w>8mW;Vi>t=xLTw((7(#Hc zekD=>R8R`%ITa1>UIlhaR3u5K%6h_>p4t;n5V1(0fD!Va+(^x%O(##hz~={piOQZV zG-Nf+viipbd{e9h1q`4m=^=g=-OZ(270eaPzJ(7~I_6lHxXvBA!Kjaa?1MGEx(z77^$bi2Y95!~x55tcV5TYe2mB z0YLdl+f~d;rwGmmF*b0J-Bip&jFL@w#y}kR$LjhNcpjS?x`>Ilx}`r$J(i?9ahBZT zke2%TInw9Aki)AB!8A3B^OjW!aRNMePpI2%EO`Y+N_<^fHyb4PMw{KLIR3zTb0RERMOQN{CJt%gK0TkWXV*sFbtFV3 zumi{wM1VM7{>ziwEOjfA>c3sNLf?U@y(Ar^J@jv$+Uq&biJr*rpS^SUp?6#da5%v_ z{A*Y^aGc1YOnWA{b7oeH*$MCFCs3mxE)!~vqj~*MQ}x6=Kav#Msw zRCN`?_fafqYH)9Jcs|6P+ocuc_h|BV&aBas3-P~lQzvC5}h<`fTYAThA* z<`(SuK)bH0;)}7@yO$PdsgJ)=2SmeI=nLUAdZG}0h8848Nyuim*JdZy{6#K7Td-Zd zvAu#gp|~wwB1szb$$Q4g`cJW@kuYd{~$t-(k@z-c24?D>GsrV73t0Zxeelw zu~sI2wF*Bdq-s@UKF5&MS1*G?LEoHeHF;0Rh2$>~Kfc5lPR_TEKB6NS)}Ff|3M>SE zNaOoxx@D@Xctx9|taJ77UMVs@WrBJ9>qevKIND~KWx#4{=;zHsCKiP@*~;Tk?A&Iz zXbmmy+Q(_T{_V`y``)s5r=`ziW*0As}*{U0r=Nz|DJ8k~Ml=pqZ-fcs;L&CY;c5_IH3oW5pjU!S2 z8=7!-kuCZ&RO@fr=E99UJ>=>1u(Ela>E+Tic#U!=Pl!Wa>OOlUkf-t|6#+P0m?f+9 zdBu94KgQtAFi32*LtFd9N}nxoy0BkpI;6BL*~O)Nr8hI@>mgA6+xNK~m=WeCQ4QJV zlggJ-h94!SO)L7o`JHKon@=<0Zb-yA&cO1az^192uFYDsMKHh1`H9>>SeCkB@sOM( zo_Ia#;qdrel!jJJQ=8jVmp6Yvld-$Rf5HTlfVV7Y*^ZeG!;3o3;t%6r{(zI-=vsCk zKPoSSjAv5mA}h|B+CG}O1h(-InuFt&E|>p*!-f}|7xUBVXDclke+4ixZ5nP@#<4cT zijZ_++M(v$8kG{0qlw)*1fG~mf%h-X4nGI~r=E;MZQRz0xjCOdS2?5G`qG=6FgSQ& zVQ5J@!I%WoS_7=7#{?|bO3uQ;YdW5Q9=`X9(h2iNwjmU4>)qT?kY&?i} zxW{9_vV!=BkKRu6WBKZ)qjWvZ7kDw?@x_;^6T`ASXhXVJfP!31tfvZbj6eV@J2l@? z-UdLYfD-k5@MqX*geD66wi-m~57?Y%&C)?_fX*s$j^MEZX$Jv^fEE4t&*2~MfmE?T zt%MXF!1uqZ^$5k6N&XS%<|}ROzN2XGDOq_4DQzT({&u5oQJ+yOgpz~d8{AK*ZA@;X zuLGAz6yf4J;s~yMPzs!llb--)R&61xULYjvUj)YY{@m^M-{0B0JlvMPAIT9z^u{xW z#k&623&l5+B*h&R*4lBrS7=3_>r*Z1Qc>Uf2ufoRSWtP&e#@KYml$>Qv!I}^Z&#JQ zqmgR2=|qBz*zJ@^?vs$qw7}lJc|s7*tdp$`=2u5de?{JdT%oKyUR$R!sEjmj@#7qs}R`IYd1c& z;8@v1E7JDELMb5O3Eouw<)GHicqCL5G#@hTd4c~BVRh=;ad>g#iOxuL{6hb7&m7rkwAp=g zPa2@Q{I8GHZI8h+656@q{>44#um$`*KB$1cI6&BP0MQ3;zy3UM0m^~yKQV;z{{6TU z?y;BE}r-QB`4H!G7GrQ&7Xyy00ih!*K zEsu6A!GAd&4xGIEh0g6Z0{6CFaAID#IDe9o_Bcq&|7`KWtHOn5?tH-`T3cO`ZR@Xv z7Bok|w0W51n9>M5?UmCr&$Y&UA9)%%m5sG|QqsMwcH@5ufT@K!-H-WhFbD&X;G}jk4c6d2)!&9f@ zz?gu!)6Q<84;iIy84_%>2Q|(z*L}z`v%g2lbrU*#9>%2m?e$1g z#09b4TSjqOgfH)ZJNL12HGo_ zaz-AY&9>)?ik!0?J2-+LAv-&{7g$0fO45hK5UEt)>VchaovQK)r!!}4HS?ouih?!| z92EA$h#xX*l0a*sLO(V5Mrse8qPdQl0L64E4lnm?mMk)NfrcJm_z*>WI3m#PJ4^+j zLk5|y=Y|FmZPL#sw08tn;@8??_A4vxTYE@&rq?va;z`RlmU16x38OLz+y2~xULWUW zX=s$ZKDNa)X)WS`T?t=F`T&pL6p#0aM$6J%YxXlnh7Dx-Q@w!NIyFbWjvJ1zw(+MJ zvpt}tDfCPJ;YS?o72>f|~P;C$e_Gpp*6PKkBkIuuH*%WA9 znDW~N47Bc@FJDuf+6!9|=Ibs3x1M?hbFl@J@b#21SbqV!z+l;+ETV~2IZY{PulIV| zx)1k?Gsz>LK*`#u&q7nZy|p=&X97w4MI>zMw#pyR4%5~yW_VnpwOFXdre*itmbN}l zsSa^_(7;sLly!m^O?XYad&Q3Ol#dgV;i%MFneU%&)2Dxj?tActc(*~SfE}$7GM-C( zT>IId`d|+(@h>IRa&sP^wXDb z6@`cyi|_S(OtvE~K5j9!cP#F0KI>cKT&SkhkTkkPm7KdD<7LU~$7^39(Bv*6BZ#$E zOxD;d^XD-!pH1^EuC>^$$DM`3?v%wE;dmr!E?R080r~W3FNsMS`@`tyKfWeB3Y_{f z5!(oHU!?9H)a|m^QEK*e!+eN}>FgdGm3-BW5D_IkU0YjUcc_~c=rL)ksl>8LG`A-d zHcihaH7}2VDbv9QwEoBqv}GFSovZv+5ByfPt~H2#mayx$h{d=gw0X_yPV|mzuYt04 z49hR{dG#lTb@SCPCZ?Lp7RyfUFKUEC1H$~Ij99aC43Dk4^gsRQI(1CRx&#oaMQYEz_{hd z=_x%^QR>+n^#t~^1tN_!3&G;A!(Vi=o}(_EQb5J9jd++h#aC zJw2f-tq|ik5qT$oDi5z_;i)t-*0HcW>@Rk|3SFfevItuXna!IwT>5a^Xwm66f(9`P#$Ma0Q1jg5OC&};eJ zRJnsUMF|^+3Z5LR;Y&ohtcpBHi{kFrS3qjYMDVH^9vE%GO*mF}#-i9|i6zee$%xI` z(iqtR13w7#*?vV7ak{jl^0bO&VLt8eix6hYBc5Gal4Z(t}AzLwesM+UO3N&rR(^yH=zCoB$n`@7ul^=>Q?HEOPJs1z4N zl+BkCwnB3KHt314RR=MzXs;slDq%9NiamR$+aWEYO1LT$SyKRE9VJ5Y&q`pZbqh!f n9MIWCI16%roBA6vQUK{qjb`#QUds`bouH@6no1Q4FM|F9kFx;U literal 0 HcmV?d00001 diff --git a/_sources/developer/getting_started.rst.txt b/_sources/developer/getting_started.rst.txt new file mode 100644 index 0000000000..b0a2316604 --- /dev/null +++ b/_sources/developer/getting_started.rst.txt @@ -0,0 +1,225 @@ + +Getting Started as a Contributer +================================ + +Icarus Verilog development is centered around the github repository at +`github.com/steveicarus/iverilog `_. +Contributing to Icarus Verilog requires a basic knowledge of git and github, +so see the github documentation for more information. The sections below will +step you through the basics of getting the source code from github, making a +branch, and submitting a pull request for review. + +Getting Icarus Verilog +---------------------- + +To start, you will need to clone the code. It is preferred that you use the +"ssh" method, and the ssh based clone with the command: + +.. code-block:: console + + % git clone git@github.com:steveicarus/iverilog.git + +This assumes that you have a github account (accounts are free) and you have +set up your ssh authentication keys. See the +`Authentication Guides here `_. + +The "git clone" command will get you all the source: + +.. code-block:: console + + % git clone git@github.com:steveicarus/iverilog.git + Cloning into 'iverilog'... + remote: Enumerating objects: 66234, done. + remote: Counting objects: 100% (6472/6472), done. + remote: Compressing objects: 100% (4123/4123), done. + remote: Total 66234 (delta 2412), reused 6039 (delta 2190), pack-reused 59762 + Receiving objects: 100% (66234/66234), 27.98 MiB | 2.53 MiB/s, done. + Resolving deltas: 100% (50234/50234), done. + % cd iverilog/ + +Normally, this is enough as you are now pointing at the most current +development code, and you have implicitly created a branch "master" that +tracks the development head. However, If you want to actually be working on a +specific version, say for example version 11, the v11-branch, you checkout +that branch with the command: + +.. code-block:: console + + % git checkout --track -b v11-branch origin/v11-branch + +This creates a local branch that tracks the v11-branch in the repository, and +switches you over to your new v11-branch. The tracking is important as it +causes pulls from the repository to re-merge your local branch with the remote +v11-branch. You always work on a local branch, then merge only when you +push/pull from the remote repository. + +Now that you've cloned the repository and optionally selected the branch you +want to work on, your local source tree may later be synced up with the +development source by using the git command: + +.. code-block:: console + + % git pull + Already up to date. + +Finally, configuration files are built by the extra step: + +.. code-block:: console + + % sh autoconf.sh + Autoconf in root... + Precompiling lexor_keyword.gperf + Precompiling vhdlpp/lexor_keyword.gperf + +You will need autoconf and gperf installed in order for the script to work. +If you get errors such as: + +.. code-block:: console + + % sh autoconf.sh + Autoconf in root... + autoconf.sh: 10: autoconf: not found + Precompiling lexor_keyword.gperf + autoconf.sh: 13: gperf: not found. + +You will need to install download and install the autoconf and gperf tools. + +Now you are ready to configure and compile the source. + +Icarus Specific Configuration Options +------------------------------------- + +Icarus takes many of the standard configuration options and those will not be +described here. The following are specific to Icarus Verilog: + +.. code-block:: none + + --enable-suffix[=suffix] + +This option allows the user to build Icarus with a default suffix or when +provided a user defined suffix. All programs or directories are tagged with +this suffix. e.g.(iverilog-0.8, vvp-0.8, etc.). The output of iverilog will +reference the correct run time files and directories. The run time will check +that it is running a file with a compatible version e.g.(you can not run a +V0.9 file with the V0.8 run time). + +A debug options is: + +.. code-block:: none + + --with-valgrind + +This option adds extra memory cleanup code and pool management code to allow +better memory leak checking when valgrind is available. This option is not +need when checking for basic errors with valgrind. + +Compiling on Linux +------------------ + +(Note: You will need to install bison, flex, g++ and gcc) This is probably the +easiest step. Given that you have the source tree from the above instructions, +the compile and install is generally as simple as: + +.. code-block:: console + + % ./configure + configure: loading site script /usr/share/site/x86_64-unknown-linux-gnu + checking build system type... x86_64-unknown-linux-gnu + checking host system type... x86_64-unknown-linux-gnu + checking for gcc... gcc + checking whether the C compiler works... yes + checking for C compiler default output file name... a.out + checking for suffix of executables... + [...and so on...] + + % make + mkdir dep + Using git-describe for VERSION_TAG + g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c main.cc -o main.o + mv main.d dep/main.d + g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c async.cc -o async.o + mv async.d dep/async.d + g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c design_dump.cc -o design_dump.o + mv design_dump.d dep/design_dump.d + g++ -DHAVE_CONFIG_H -I. -Ilibmisc -Wall -Wextra -Wshadow -g -O2 -MD -c discipline.cc -o discipline.o + [...and so on...] + +The end result is a complete build of Icarus Verilog. You can install your +compiled version with a command like this: + +.. code-block:: console + + % sudo make install + +Regression Tests +---------------- + +Icarus Verilog comes with a fairly extensive regression test suite. As of +2022, that test suite is included with the source in the "ivtest" +directory. Contained in that directory are a couple driver scripts that run +all the regression tests on the installed version of Icarus Verilog. So for +example: + +.. code-block:: console + + % cd ivtest + % ./vvp_reg.pl --strict + +will run all the regression tests for the simulation engine. (This is what +most people will want to do.) You should rerun this test before submitting +patches to the developers. Also, if you are adding a new feature, you should +add test programs to the regression test suite to validate your new feature +(or bug fix.) + +Note that pull requests will be required to pass these regression tests before +being merged. + +Forks, Branches and Pull Requests +--------------------------------- + +Currently, the preferred way to submit patches to Icarus Verilog is via pull +requests. +`Pull requests `_ +can be created from the main repository if you have write access (very few +people have write access) or more commonly from a fork, so the first step is +to create a fork that you can work with. It is easy enough to create a fork, +just go to the +`github.com/steveicarus/iverilog `_ +page and use the "fork" button in the upper right corner. This will create +a new repository that you can clone instead of the steveicarus/iverilog +repository. You then use your local repository to create feature branches, +then submit them for inclusion in the main repository as pull +requests. Remember to `synchronize your fork +`_ +periodically with the main repository. This will make sure your work is based +on the latest upstream and avoid merge conflicts. + +Create your patch by first creating a branch that contains your commits: + +.. code-block:: console + + % git checkout -b my-github-id/branch-name + +We are encouraging using this scheme for naming your branches that are +destined for pull requests. Use your github id in the branch name. So for +example: + +.. code-block:: console + + % git checkout -b steveicarus/foo-feature + +Do your work in this branch, then when you are ready to create a pull request, +first push the branch up to github: + +.. code-block:: console + + % git push -u origin my-github-id/branch-name + +Then go to github.com to create your pull request. `Create your pull request +against the "master" branch of the upstream repository +`_, +or the version branch that you are working on. Your pull reuqest will be run +through continuous integration, and reviewed by one of the main +authors. Feedback may be offered to your PR, and once accepted, an approved +individual will merge it for you. Then you are done. + diff --git a/_sources/developer/glossary.rst.txt b/_sources/developer/glossary.rst.txt new file mode 100644 index 0000000000..4bbf648147 --- /dev/null +++ b/_sources/developer/glossary.rst.txt @@ -0,0 +1,48 @@ + +Glossary +======== + +Throughout Icarus Verilog descriptions and source code, I use a +variety of terms and acronyms that might be specific to Icarus +Verilog, have an Icarus Verilog specific meaning, or just aren't +widely known. So here I define these terms. + + +LRM - Language Reference Manual + This is a generic acronym, but in the Verilog world we sometimes + mean *the* language reference manual, the IEEE1364 standard. + + +PLI - Programming Language Interface + This is a C API into Verilog simulators that is defined by the + IEEE1364. There are two major interfaces, sometimes called PLI 1 + and PLI 2. PLI 2 is also often called VPI. + + +UDP - User Defined Primitive + These are objects that Verilog programmers define with the + "primitive" keyword. They are truth-table based devices. The + syntax for defining them is described in the LRM. + + +VPI - Verilog Procedural Interface + This is the C API that is defined by the Verilog standard, and + that Icarus Verilog partially implements. See also PLI. + + +VVM - Verilog Virtual Machine + This is the Icarus Verilog runtime that works with the code + generator that generates C++. + + +VVP - Verilog Virtual Processor + This is the Icarus Verilog runtime that reads in custom code in a + form that I call "VVP Assembly". + +LPM - Library of Parameterized Modules + LPM (Library of Parameterized Modules) is EIS-IS standard 103-A. It is + a standard library of abstract devices that are designed to be close + enough to the target hardware to be easily translated, yet abstract + enough to support a variety of target technologies without excessive + constraints. Icarus Verilog uses LPM internally to represent idealized + hardware, especially when doing target neutral synthesis. diff --git a/_sources/developer/guide/cadpli/cadpli.rst.txt b/_sources/developer/guide/cadpli/cadpli.rst.txt new file mode 100644 index 0000000000..c08b617a76 --- /dev/null +++ b/_sources/developer/guide/cadpli/cadpli.rst.txt @@ -0,0 +1,34 @@ + +Cadence PLI1 Modules +==================== + +With the cadpli module, Icarus Verilog is able to load PLI1 +applications that were compiled and linked to be dynamic loaded by +Verilog-XL or NC-Verilog. This allows Icarus Verilog users to run +third-party modules that were compiled to interface with XL or +NC. Obviously, this only works on the operating system that the PLI +application was compiled to run on. For example, a Linux module can +only be loaded and run under Linux. + +Icarus Verilog uses an interface module, the "cadpli" module, to +connect the worlds. This module is installed with Icarus Verilog, and +is invoked by the usual -m flag to iverilog or vvp. This module in +turn scans the extended arguments, looking for +cadpli= arguments. The +latter specify the share object and bootstrap function for running the +module. For example, to run the module product.so, that has the +bootstrap function "my_boot":: + + vvp -mcadpli a.out -cadpli=./product.so:my_boot + +The "-mcadpli" argument causes vvp to load the cadpli.vpl library +module. This activates the -cadpli= argument interpreter. The +-cadpli=: argument, then, causes vvp, through the +cadpli module, to load the loadable PLI application, invoke the +my_boot function to get a veriusertfs table, and scan that table to +register the system tasks and functions exported by that object. The +format of the -cadpli= extended argument is essentially the same as +the +loadpli1= argument to Verilog-XL. + +The integration from this point is seamless. The PLI application +hardly knows that it is being invoked by Icarus Verilog instead of +Verilog-XL, so operates as it would otherwise. diff --git a/_sources/developer/guide/index.rst.txt b/_sources/developer/guide/index.rst.txt new file mode 100644 index 0000000000..bd2ad2d745 --- /dev/null +++ b/_sources/developer/guide/index.rst.txt @@ -0,0 +1,169 @@ + +Developer Guide +=============== + +The developer guide is intended to give you a gross structure of the +Icarus Verilog compiler source. This will help orient you to the +source code itself, so that you can find the global parts where you +can look for even better detail. + +The documentation for getting, building and installing Icarus Verilog +is kept and maintained at :doc:`Getting Started as a Contributer <../getting_started>` + +See the Installation Guide for getting the current source from the git +repository (and how to use the git repository) and see the Developer Guide +for instructions on participating in the Icarus Verilog development process. +That information will not be repeated here. + +Scroll down to a listing with further readings. + +Compiler Components +------------------- + +- The compiler driver (driver/) + +This is the binary that is installed as "iverilog". This program takes +the command line arguments and assembles invocations of all the other +subcommands to perform the steps of compilation. + +- The preprocessor (ivlpp/) + +This implements the Verilog pre-processor. In Icarus Verilog, the +compiler directives \`define, \`include, \`ifdef and etc. are implemented +in an external program. The ivlpp/ directory contains the source for +this program. + +- The core compiler (root directory) + +The "ivl" program is the core that does all the Verilog compiler +processing that is not handled elsewhere. This is the main core of the +Icarus Verilog compiler, not the runtime. See below for more details +on the core itself. + +- The loadable code generators (tgt-\*/) + +This core compiler, after it is finished with parsing and semantic +analysis, uses loadable code generators to emit code for supported +targets. The tgt-\*/ directories contains the source for the target +code generators that are bundled with Icarus Verilog. The tgt-vvp/ +directory in particular contains the code generator for the vvp +runtime. + + +Runtime Components +------------------ + +- The vvp runtime (vvp/) + +This program implements the runtime environment for Icarus +Verilog. It implements the "vvp" command described in the user +documentation. See the vvp/ subdirectory for further developer +documentation. + +- The system tasks implementations (vpi/) + +The standard Verilog system tasks are implemented using VPI (PLI-2) +and the source is in this subdirectory. + +- The PLI-1 compatibility library (libveriuser/) + +The Icarus Verilog support for the deprecated PLI-1 is in this +subdirectory. The vvp runtime does not directly support the +PLI-1. Instead, the libveriuser library emulates it using the builtin +PLI-2 support. + +- The Cadence PLI module compatibility module (cadpli/) + +It is possible in some specialized situations to load and execute +PLI-1 code written for Verilog-XL. This directory contains the source +for the module that provides the Cadence PLI interface. + + +The Core Compiler +----------------- + +The "ivl" binary is the core compiler that does the heavy lifting of +compiling the Verilog source (including libraries) and generating the +output. This is the most complex component of the Icarus Verilog +compilation system. + +The process in the abstract starts with the Verilog lexical analysis +and parsing to generate an internal "pform". The pform is then +translated by elaboration into the "netlist" form. The netlist is +processed by some functors (which include some optimizations and +optional synthesis) then is translated into the ivl_target internal +form. And finally, the ivl_target form is passed via the ivl_target.h +API to the code generators. + +- Lexical Analysis + +Lexical analysis and parsing use the tools "flex", "gperf", and +"bison". The "flex" input file "lexor.lex" recognizes the tokens in +the input stream. This is called "lexical analysis". The lexical +analyzer also does some processing of compiler directives that are not +otherwise taken care of by the external preprocessor. The lexical +analyzer uses a table of keywords that is generated using the "gperf" +program and the input file "lexor_keywords.gperf". This table allows +the lexical analyzer to efficiently check input words with the rather +large set of potential keywords. + +- Parsing + +The parser input file "parse.y" is passed to the "bison" program to +generate the parser. The parser uses the functions in parse*.h, +parse*.cc, pform.h, and pform*.cc to generate the pform from the +stream of input tokens. The pform is what compiler writers call a +"decorated parse tree". + +The pform itself is described by the classes in the header files +"PScope.h", "Module.h", "PGenerate.h", "Statement.h", and +"PExpr.h". The implementations of the classes in those header files +are in the similarly named C++ files. + +- Elaboration + +Elaboration transforms the pform to the netlist form. Elaboration is +conceptually divided into several major steps: Scope elaboration, +parameter overrides and defparam propagation, signal elaboration, and +statement and expression elaboration. + +The elaboration of scopes and parameter overrides and defparam +propagation are conceptually separate, but are in practice +intermingled. The elaboration of scopes scans the pform to find and +instantiate all the scopes of the design. New scopes are created by +instantiation of modules (starting with the root instances) by user +defined tasks and functions, named blocks, and generate schemes. The +elaborate_scope methods implement scope elaboration, and the +elab_scope.cc source file has the implementations of those +methods. + +The elaborate.cc source file contains the initial calls to the +elaborate_scope for the root scopes to get the process started. In +particular, see the "elaborate" function near the bottom of the +elaborate.cc source file. The calls to Design::make_root_scope create +the initial root scopes, and the creation and enqueue of the +elaborate_root_scope_t work items primes the scope elaboration work +list. + +Intermingled in the work list are defparms work items that call the +Design::run_defparams and Design::evaluate_parameters methods that +override and evaluate parameters. The override and evaluation of +parameters must be intermingled with the elaboration of scopes because +the exact values of parameters may impact the scopes created (imagine +generate schemes and instance arrays) and the created scopes in turn +create new parameters that need override and evaluation. + +Further Reading +--------------- + +For further information on the individual parts of Icarus Verilog, see this listing: + +.. toctree:: + :maxdepth: 2 + + ivl/index + vvp/index + tgt-vvp/tgt-vvp + vpi/index + cadpli/cadpli + misc/index diff --git a/_sources/developer/guide/ivl/attributes.rst.txt b/_sources/developer/guide/ivl/attributes.rst.txt new file mode 100644 index 0000000000..48fb143e76 --- /dev/null +++ b/_sources/developer/guide/ivl/attributes.rst.txt @@ -0,0 +1,91 @@ + +Icarus Verilog Attributes +========================= + +Attribute Naming Conventions +---------------------------- + +Attributes that are specific to Icarus Verilog, and are intended to be +of use to programmers, start with the prefix "ivl\_". + +Attributes with the "_ivl_" prefix are set aside for internal +use. They may be generated internally by the compiler. They need not +be documented here. + +Attributes To Control Synthesis +------------------------------- + +The following is a summary of Verilog attributes that Icarus Verilog +understands within Verilog source files to control synthesis +behavior. This section documents generic synthesis attributes. For +target specific attributes, see target specific documentation. + +These attributes only effect the behavior of the synthesizer. For +example, the ivl_combinational will not generate an error message +if the Verilog is being compiled for simulation. (It may generate a +warning.) + + +* Attributes for "always" and "initial" statements + +(\* ivl_combinational \*) + + This attribute tells the compiler that the statement models + combinational logic. If the compiler finds that it cannot make + combinational logic out of a marked always statement, it will + report an error. + + This attribute can be used to prevent accidentally inferring + latches or flip-flops where the user intended combinational + logic. + +(\* ivl_synthesis_on \*) + + This attribute tells the compiler that the marked always statement + is synthesizable. The compiler will attempt to synthesize the + code in the marked "always" statement. If it cannot in any way + synthesize it, then it will report an error. + +(\* ivl_synthesis_off \*) + + If this value is attached to an "always" statement, then the + compiler will *not* synthesize the "always" statement. This can be + used, for example, to mark embedded test bench code. + + +* Attributes for modules + +(\* ivl_synthesis_cell \*) + + If this value is attached to a module during synthesis, that + module will be considered a target architecture primitive, and + its interior will not be synthesized further. The module can + therefore hold a model for simulation purposes. + + +* Attributes for signals (wire/reg/integer/tri/etc.) + +(\* PAD = "" \*) + + If this attribute is attached to a signal that happens to be a + root module port, then targets that support it will use the string + value as a list of pin assignments for the port/signal. The format + is a comma separated list of location tokens, with the format of + the token itself defined by the back-end tools in use. + +* Other Attributes + +[ none defined yet ] + + +Misc +---- + +(\* _ivl_schedule_push \*) + + If this attribute is attached to a thread object (always or + initial statement) then the vvp code generator will generate code + that causes the scheduler to push this thread at compile time. The + compiler may internally add this attribute to always statements if + it detects that it is combinational. This helps resolve time-0 + races. diff --git a/_sources/developer/guide/ivl/index.rst.txt b/_sources/developer/guide/ivl/index.rst.txt new file mode 100644 index 0000000000..c581fed5ae --- /dev/null +++ b/_sources/developer/guide/ivl/index.rst.txt @@ -0,0 +1,12 @@ + +IVL - The Core Compiler +======================= + +.. toctree:: + :maxdepth: 1 + + netlist + attributes + ivl_target + lpm + t-dll diff --git a/_sources/developer/guide/ivl/ivl_target.rst.txt b/_sources/developer/guide/ivl/ivl_target.rst.txt new file mode 100644 index 0000000000..6deacd901f --- /dev/null +++ b/_sources/developer/guide/ivl/ivl_target.rst.txt @@ -0,0 +1,131 @@ + +Loadable Target API (ivl_target) +================================ + +In addition to the standard VPI API, Icarus Verilog supports a non-standard +loadable target module API. This API helps C programmers write modules that +Icarus Verilog can use to generate code. These modules are used at compile +time to write the elaborated design to the simulation or netlist files. For +example, the vvp code generator is a loadable target module that writes vvp +code into the specified file. + +Loadable target modules gain access to the 'elaborated' design. That means, +the source files have been checked for syntax and correctness, any synthesis +and general optimization steps have been performed, and what is left is a +design that reflects but is not exactly the same as the input Verilog source +code. This relieves the modules of the burden of supporting all the odd +corners and complexities of the Verilog language. + +The Target Module API +--------------------- + +The API is defined in the header file "ivl_target.h" which is installed with +Icarus Verilog. The header defines the functions that the module writer can +use to get at the elaborated design during the course of writing the output +format. + +The target module API function "target_design" is special in that the API does +not provide this function: The target module itself provides it. When the +compiler loads the target module, it invokes the "target_design" function with +a handle to the design. This is the point where the target module takes over +to process the design. + +Compiling Target Modules +------------------------ + +Compiling loadable target modules is similar to compiling VPI modules, in that +the module must be compiled with the "-fPIC" flag to gcc, and linked with the +"-shared" flag. The module that you compile is then installed in a place where +the "iverilog" command can find it, and configuration files are adjusted to +account for the new module. + +This code:: + + # include + + int target_design(ivl_design_t des) + { + return 0; + } + +is an example module that we can write into the file "empty.c"; and let us +compile it into the module file "empty.tgt" like so:: + + % gcc -o empty.tgt -fpic -shared empty.c + +This makes the "empty.tgt" file an a dynamically loaded shared object. + +Creating the Target Config File +------------------------------- + +The target config file tells the Icarus Verilog core how to process your new +code generator. The ivl core expects two configuration files: the name.conf +and the name-s.config files. The "-s" version is what is used if the user +gives the "-S" (synthesis) flag on the command line. + +The stub target, included in most distributions, demonstrates the config +files. The "stub.conf" file is:: + + functor:cprop + functor:nodangle + -t:dll + flag:DLL=stub.tgt + +and the "stub-s.conf" file is:: + + functor:synth2 + functor:synth + functor:syn-rules + functor:cprop + functor:nodangle + -t:dll + flag:DLL=stub.tgt + +Note that the "stub-s.conf" file contains more lines to invoke internal +synthesis functions, whereas the "stub.conf" invokes only the basic +optimization steps. + +In general, only the last line (The "flag:DLL=.tgt" record) varies for +each target. For your target, replace the with the name of your target +and you have a configuration file ready to install. Note that this is the name +of your target module. This is in fact how the config file tells the compiler +the name of your module. + +The rest of the config file is best taken as boiler plate and installed as is, +with one difference. If your target is a synthesis target (for example a mosis +code generator or a pld code generator) that expects synthesis to happen, then +it makes the most sense to create both your config file like the "stub-s.conf" +config file. This causes the compiler to do synthesis for your target whether +the user gives the "-S" flag or not. + +Installing the Target Module +---------------------------- + +Finally, the "empty.conf", the "empty-s.conf" and the "empty.tgt" files need +to be installed. Where they go depends on your system, but in Linux they are +normally installed in "/usr/lib/ivl". + + +LPM Devices +----------- + +All LPM devices support a small set of common LPM functions, as +described in the ivl_target header file. The ivl_lpm_t object has a +type enumerated by ivl_lpm_type_t, and that type is accessible via the +ivl_lpm_type function. + +The following are type specific aspects of LPM devices. + +* IVL_LPM_UFUNC + +This LPM represents a user defined function. It is a way to connect +behavioral code into a structural network. The UFUNC device has a +vector output and a set of inputs. The ivl_lpm_define function returns +the definition as an ivl_scope_t object. + +The output vector is accessible through the ivl_lpm_q, and the output +has the width defined by ivl_lpm_width. This similar to most every +other LPM device with outputs. + +There are ivl_lpm_size() input ports, each with the width +ivl_lpm_data2_width(). The actual nexus is indexed by ivl_lpm_data2(). diff --git a/_sources/developer/guide/ivl/lpm.rst.txt b/_sources/developer/guide/ivl/lpm.rst.txt new file mode 100644 index 0000000000..0774be457f --- /dev/null +++ b/_sources/developer/guide/ivl/lpm.rst.txt @@ -0,0 +1,28 @@ + +What Is LPM +=========== + +LPM (Library of Parameterized Modules) is EIS-IS standard 103-A. It is +a standard library of abstract devices that are designed to be close +enough to the target hardware to be easily translated, yet abstract +enough to support a variety of target technologies without excessive +constraints. Icarus Verilog uses LPM internally to represent idealized +hardware, especially when doing target neutral synthesis. + +In general, the user does not even see the LPM that Icarus Verilog +generates, because the LPM devices are translated into technology +specific devices by the final code generator or target specific +optimizers. + +Internal Uses Of LPM +-------------------- + +Internally, Icarus Verilog uses LPM devices to represent the design in +abstract, especially when synthesizing such functions as addition, +flip-flops, etc. The `synth` functor generates LPM modules when +interpreting procedural constructs. The functor generates the LPM +objects needed to replace a behavioral description, and uses +attributes to tag the devices with LPM properties. + +Code generators need to understand the supported LPM devices so that +they can translate the devices into technology specific devices. diff --git a/_sources/developer/guide/ivl/netlist.rst.txt b/_sources/developer/guide/ivl/netlist.rst.txt new file mode 100644 index 0000000000..0baaea0d6d --- /dev/null +++ b/_sources/developer/guide/ivl/netlist.rst.txt @@ -0,0 +1,285 @@ + +Netlist Format +============== + +The output from the parse and elaboration steps is a "netlist" rooted +in a Design object. Parsing translates the design described in the +initial source file into a temporary symbolic "pform". Elaboration +then expands the design, resolving references and expanding +hierarchies, to produce a flattened netlist. This is the form that +optimizers and code generators use. + +The design optimization processes all manipulate the netlist, +translating it to a (hopefully) better netlist after each step. The +complete netlist is then passed to the code generator, the emit +function, where the final code (in the target format) is produced. + +Structural Items: NetNode and NetNet +------------------------------------ + +Components and wires, memories and registers all at their base are +either NetNode objects or NetNet objects. Even these classes are +derived from the NetObj class. + +All NetNode and NetNet objects have a name and some number of +pins. The name usually comes from the Verilog source that represents +that object, although objects that are artifacts of elaboration will +have a generated (and probably unreadable) name. The pins are the +ports into the device. NetNode objects have a pin for each pin of the +component it represents, and NetNet objects have a pin for each signal +in the vector. + +Node and net pins can be connected together via the connect +function. Connections are transitive (A==B and B==c means A==C) so +connections accumulate on a link as items are connected to it. The +destructors for nets and nodes automatically arrange for pins to be +disconnected when the item is deleted, so that the netlist can be +changed during processing. + +Structural Links +---------------- + +The NetNode and NetNet classes contain arrays of Link objects, one +object per pin. Each pin is a single bit. The Link objects link to all +the NetNode and NetNet objects' links that are connected together in +the design, and to a Nexus object. This way, code that examines a node +of the design can discover what is connected to each pin. + +The connected set of links also has common properties that are stored +or access from the Nexus object. All the Links that are connected +together are also connected to a single Nexus object. This object is +useful for accessing the properties and values that come from the +connected set of links. The Nexus object is also handy for iterating +over the connected set of Links. + +See the Link class definition in netlist.h for a description of the link +methods, and the Nexus class for nexus global methods. + +Currently, a link has 3 possible direction properties: + + PASSIVE -- These pins are sampled by the object that holds the + pin based on some external event. These are used, + for example, by NetESignal objects that read a + point for a procedural expression. + + INPUT -- These pins potentially react to the setting of its + input. + + OUTPUT -- These pins potentially drive the node. (They may be + three-state.) + + +Behavioral Items: NetProcTop, NetProc and derived classes +--------------------------------------------------------- + +Behavioral items are not in general linked to the netlist. Instead, +they represent elaborated behavioral statements. The type of the object +implies what the behavior of the statement does. For example, a +NetCondit object represents an `if` statement, and carries a +condition expression and up to two alternative sub-statements. + +At the root of a process is a NetProcTop object. This class carries a +type flag (initial or always) and a single NetProc object. The +contained statement may, depending on the derived class, refer to +other statements, compound statements, so on. But at the root of the +tree is the NetProcTop object. The Design class keeps a list of the +elaborated NetProcTop objects. That list represents the list of +processes in the design. + +Interaction Of Behavioral And Structural: NetAssign\_ +----------------------------------------------------- + +The behavioral statements in a Verilog design effect the structural +aspects through assignments to registers. Registers are structural +items represented by the NetNet class, linked to the assignment +statement through pins. This implies that the l-value of an assignment +is structural. It also implies that the statement itself is +structural, and indeed it is derived from NetNode. + +The NetAssign\_ class is also derived from the NetProc class because +what it does is brought on by executing the process. By multiple +inheritance we have therefore that the assignment is both a NetNode +and a NetProc. The NetAssign\_ node has pins that represent the l-value +of the statement, and carries behavioral expressions that represent +the r-value of the assignment. + +Memories +-------- + +The netlist form includes the NetMemory type to hold the content of a +memory. Instances of this type represent the declaration of a memory, +and occur once for each memory. References to the memory are managed +by the NetEMemory and NetAssignMem\_ classes. + +An instance of the NetEMemory class is created whenever a procedural +expression references a memory element. The operand is the index to +use to address (and read) the memory. + +An instance of the NetAssignMem\_ class is created when there is a +procedural assignment to the memory. The NetAssignMem\_ object +represents the l-value reference (a write) to the memory. As with the +NetEMemory class, this is a procedural reference only. + +When a memory reference appears in structural context (i.e. continuous +assignments) elaboration creates a NetRamDq. This is a LPM_RAM_DQ +device. Elaboration leaves the write control and data input pins +unconnected for now, because memories cannot appear is l-values of +continuous assignments. However, the synthesis functor may connect +signals to the write control lines to get a fully operational RAM. + +By the time elaboration completes, there may be many NetAssignMem\_, +NetEMemory and NetRamDq objects referencing the same NetMemory +object. Each represents a port into the memory. It is up to the +synthesis steps (and the target code) to figure out what to do with +these ports. + +Expressions +----------- + +Expressions are represented as a tree of NetExpr nodes. The NetExpr +base class contains the core methods that represent an expression +node, including virtual methods to help with dealing with nested +complexities of expressions. + +Expressions (as expressed in the source and p-form) may also be +elaborated structurally, where it makes sense. For example, assignment +l-value expressions are represented as connections to pins. Also, +continuous assignment module items are elaborated as gates instead of +as a procedural expression. Event expressions are also elaborated +structurally as events are like devices that trigger behavioral +statements. + +However, typical expressions the behavioral description are +represented as a tree of NetExpr nodes. The derived class of the node +encodes what kind of operator the node represents. + +Expression Bit Width +-------------------- + +The expression (represented by the NetExpr class) has a bit width that +it either explicitly specified, or implied by context or contents. +When each node of the expression is first constructed during +elaboration, it is given, by type and parameters, an idea what its +width should be. It certain cases, this is definitive, for example +with signals. In others, it is ambiguous, as with unsized constants. + +As the expression is built up by elaboration, operators that combine +expressions impose bit widths of the environment or expose the bit +widths of the sub expressions. For example, the bitwise AND (&) +operator has a bit size implied by its operands, whereas the +comparison (==) operator has a bit size of 1. The building up of the +elaborated expression checks and adjusts the bit widths as the +expression is built up, until finally the context of the expression +takes the final bit width and makes any final adjustments. + +The NetExpr::expr_width() method returns the calculated (or guessed) +expression width. This method will return 0 until the width is set by +calculation or context. If this method returns false, then it is up to +the context that wants the width to set one. The elaboration phase +will call the NetExpr::set_width method on an expression as soon as it +gets to a point where it believes that it knows what the width should +be. + +The NetExpr::set_width(unsigned) virtual method is used by the context +of an expression node to note to the expression that the width is +determined and please adapt. If the expression cannot reasonably +adapt, it will return false. Otherwise, it will adjust bit widths and +return true. + +:: + + I do not yet properly deal with cases where elaboration knows for + certain that the bit width does not matter. In this case, I + really should tell the expression node about it so that it can + pick a practical (and optimal) width. + +Interaction Of Expressions And Structure: NetESignal +---------------------------------------------------- + +The NetAssign\_ class described above is the means for processes to +manipulate the net, but values are read from the net by NetESignal +objects. These objects are class NetExpr because they can appear in +expressions (and have width). They are not NetNode object, but hold +pointers to a NetNet object, which is used to retrieve values with the +expression is evaluated. + + +Hierarchy In Netlists +--------------------- + +The obvious hierarchical structure of Verilog is the module. The +Verilog program may contain any number of instantiations of modules in +order to form an hierarchical design. However, the elaboration of the +design into a netlist erases module boundaries. Modules are expanded +each place they are used, with the hierarchical instance name used to +name the components of the module instance. However, the fact that a +wire or register is a module port is lost. + +The advantage of this behavior is first the simplification of the +netlist structure itself. Backends that process netlists only need to +cope with a list of nets, a list of nodes and a list of +processes. This eases the task of the backend code generators. + +Another advantage of this flattening of the netlist is that optimizers +can operate globally, with optimizations freely crossing module +boundaries. This makes coding of netlist transform functions such as +constant propagation more effective and easier to write. + + +Scope Representation In Netlists +-------------------------------- + +In spite of the literal flattening of the design, scope information is +preserved in the netlist, with the NetScope class. The Design class +keeps a single pointer to the root scope of the design. This is the +scope of the root module. Scopes that are then created within that +(or any nested) module are placed as children of the root scope, and +those children can have further children, and so on. + +Each scope in the tree carries its own name, and its relationship to +its parent and children. This makes it possible to walk the tree of +scopes. In practice, the walking of the scopes is handled by recursive +methods. + +Each scope also carries the parameters that are applicable to the +scope itself. The parameter expression (possibly evaluated) can be +located by name, given the scope object itself. The scan of the pform +to generate scopes also places the parameters that are declared in the +scope. Overrides are managed during the scan, and once the scan is +complete, defparam overrides are applied. + + +Tasks In Netlists +----------------- + +The flattening of the design does not include tasks and named +begin-end blocks. Tasks are behavioral hierarchy (whereas modules are +structural) so do not easily succumb to the flattening process. In +particular, it is logically impossible to flatten tasks that +recurse. (The elaboration process does reserve the right to flatten +some task calls. C++ programmers recognize this as inlining a task.) + + +Time Scale In Netlists +---------------------- + +The Design class and the NetScope classes carry time scale and +resolution information of the elaborated design. There is a global +resolution, and there are scope specific units and resolutions. Units +and resolutions are specified as signed integers, and interpreted as +the power of 10 of the value. For example, a resolution "-9" means +that "1" is 1ns (1e-9). The notation supports units from -128 to +127. +It is up to the back-ends to interpret "-4" as "100us". + +Delays are expressed in the netlist by integers. The units of these +delays are always given in the units of the design precision. This +allows everything to work with integers, and generally places the +burden of scaling delays into elaboration. This is, after all, a +common task. The Design::get_precision() method gets the global design +precision. + +Each NetScope also carries its local time_units and time_precision +values. These are filled in during scope elaboration and are used in +subsequent elaboration phases to arrange for scaling of delays. This +information can also be used by the code generator to scale times back +to the units of the scope, if that is desired. diff --git a/_sources/developer/guide/ivl/t-dll.rst.txt b/_sources/developer/guide/ivl/t-dll.rst.txt new file mode 100644 index 0000000000..fa446614a4 --- /dev/null +++ b/_sources/developer/guide/ivl/t-dll.rst.txt @@ -0,0 +1,61 @@ + +Loadable Targets +================ + +Icarus Verilog supports dynamically loading code generator modules to +perform the back-end processing of the completed design. The user +specifies on the command line the module to load. The compiler loads +the module (once the design is compiled and elaborated) and calls it +to finally handle the design. + +Loadable target modules implement a set of functions that the core +compiler calls to pass the design to it, and the module in turn uses a +collection of functions in the core (the API) to access details of the +design. + +Loading Target Modules +---------------------- + +The target module loader is invoked with the ivl flag "-tdll". That +is, the DLL loader is a linked in target type. The name of the target +module to load is then specified with the DLL flag, i.e. "-fDLL=". + +Compiling Target Modules +------------------------ + + + +Loadable Target Module Api +-------------------------- + +The target module API is defined in the ivl_target.h header file. This +declares all the type and functions that a loadable module needs to +access the design. + + +About Specific Expression Types +------------------------------- + +In this section find notes about the various kinds of expression +nodes. The notes here are in addition to the more general +documentation in the ivl_target.h header file. + +* IVL_EX_CONCAT + + The concatenation operator forms an expression node that holds the + repeat count and all the parameter expressions. The repeat count is + an integer that is calculated by the core compiler so it fully + evaluated, and *not* an expression. + + The parameter expressions are retrieved by the ivl_expr_parm method, + with the index increasing as parameters go from left to right, from + most significant to least significant. (Note that this is different + from the order of bits within an expression node.) + +* IVL_EX_NUMBER + + This is a constant number. The width is fully known, and the bit + values are all represented by the ASCII characters 0, 1, x or z. The + ivl_expr_bits method returns a pointer to the least significant bit, + and the remaining bits are ordered from least significant to most + significant. For example, 5'b1zzx0 is the 5 character string "0xzz1". diff --git a/_sources/developer/guide/misc/ieee1364-notes.rst.txt b/_sources/developer/guide/misc/ieee1364-notes.rst.txt new file mode 100644 index 0000000000..39785298cf --- /dev/null +++ b/_sources/developer/guide/misc/ieee1364-notes.rst.txt @@ -0,0 +1,501 @@ + +IEEE1364 Notes +============== + +The IEEE1364 standard is the bible that defines the correctness of the +Icarus Verilog implementation and behavior of the compiled +program. The IEEE1364.1 is also referenced for matters of +synthesis. So the ultimate definition of right and wrong comes from +those documents. + +That does not mean that a Verilog implementation is fully +constrained. The standard document allows for implementation specific +behavior that, when properly accounted for, does not effect the +intended semantics of the specified language. It is therefore possible +and common to write programs that produce different results when run +by different Verilog implementations. + + +Standardization Issues +---------------------- + +These are some issues where the IEEE1364 left unclear, unspecified or +simply wrong. I'll try to be precise as I can, and reference the +standard as needed. I've made implementation decisions for Icarus +Verilog, and I will make clear what those decisions are and how they +affect the language. + +* OBJECTS CAN BE DECLARED ANYWHERE IN THE MODULE + +Consider this module:: + + module sample1; + initial foo = 1; + reg foo; + wire tmp = bar; + initial #1 $display("foo = %b, bar = %b", foo, tmp); + endmodule + +Notice that the `reg foo;` declaration is placed after the first +initial statement. It turns out that this is a perfectly legal module +according to the -1995 and -2000 versions of the standard. The +statement `reg foo;` is a module_item_declaration which is in turn a +module_item. The BNF in the appendix of IEEE1364-1995 treats all +module_item statements equally, so no order is imposed. + +Furthermore, there is no text (that I can find) elsewhere in the +standard that imposes any ordering restriction. The sorts of +restrictions I would look for are "module_item_declarations must +appear before all other module_items" or "variables must be declared +textually before they are referenced." Such statements simply do not +exist. (Personally, I think it is fine that they don't.) + +The closest is the rules for implicit declarations of variables that +are otherwise undeclared. In the above example, `bar` is implicitly +declared and is therefore a wire. However, although `initial foo = 1;` +is written before foo is declared, foo *is* declared within the +module, and declared legally by the BNF of the standard. + +Here is another example:: + + module sample2; + initial x.foo = 1; + test x; + initial #1 $display("foo = %b", x.foo); + endmodule + + module test; + reg foo; + endmodule; + +From this example one can clearly see that foo is once again declared +after its use in behavioral code. One also sees a forward reference of +an entire module. Once again, the standard places no restriction on +the order of module declarations in a source file, so this program is, +according to the standard, perfectly well formed. + +Icarus Verilog interprets both of these examples according to "The +Standard As I Understand It." However, commercial tools in general +break down with these programs. In particular, the first example +may generate different errors depending on the tool. The most common +error is to claim that `foo` is declared twice, once (implicitly) as +a wire and once as a reg. + +So the question now becomes, "Is the standard broken, or are the tools +limited?" Coverage of the standard seems to vary widely from tool to +tool so it is not clear that the standard really is at fault. It is +clear, however, that somebody goofed somewhere. + +My personal opinion is that there is no logical need to require that +all module_item_declarations precede any other module items. I +personally would oppose such a restriction. It may make sense to +require that declarations of variables within a module be preceded by +their use, although even that is not necessary for the implementation +of efficient compilers. + +However, the existence hierarchical naming syntax as demonstrated in +sample2 can have implications that affect any declaration order +rules. When reaching into a module with a hierarchical name, the +module being referenced is already completely declared (or not +declared at all, as in sample2) so module_item order is completely +irrelevant. But a "declare before use" rule would infect module +ordering, by requiring that modules that are used be first defined. + + +* TASK AND FUNCTION PARAMETERS CANNOT HAVE EXPLICIT TYPES + +Consider a function negate that wants to take a signed integer value +and return its negative:: + + function integer negate; + input [15:0] val; + negate = -val; + endfunction + +This is not quite right, because the input is implicitly a reg type, +which is unsigned. The result, then, will always be a negative value, +even if a negative val is passed in. + +It is possible to fix up this specific example to work properly with +the bit pattern of a 16bit number, but that is not the point. What's +needed is clarification on whether an input can be declared in the +port declaration as well as in the contained block declaration. + +As I understand the situation, this should be allowed:: + + function integer negate; + input [15:0] val; + reg signed [15:0] val; + negate = -val; + endfunction + +In the -1995 standard, the variable is already implicitly a reg if +declared within a function or task. However, in the -2000 standard +there is now (as in this example) a reason why one might want to +actually declare the type explicitly. + +I think that a port *cannot* be declared as an integer or time type +(though the result can) because the range of the port declaration must +match the range of the integer/time declaration, but the range of +integers is unspecified. This, by the way, also applies to module +ports. + +With the above in mind, I have decided to *allow* function and task +ports to be declared with types, as long as the types are variable +types, such as reg or integer. Without this, there would be no +portable way to pass integers into functions/tasks. The standard does +not say it is allowed, but it doesn't *disallow* it, and other +commercial tools seem to work similarly. + + +* ROUNDING OF TIME + +When the \`timescale directive is present, the compiler is supposed to +round fractional times (after scaling) to the nearest integer. The +confusing bit here is that it is apparently conventional that if the +\`timescale directive is *not* present, times are rounded towards zero +always. + + +* VALUE OF X IN PRIMITIVE OUTPUTS + +The IEEE1364-1995 standard clearly states in Table 8-1 that the x +symbols is allowed in input columns, but is not allowed in +outputs. Furthermore, none of the examples have an x in the output of +a primitive. Table 8-1 in the IEEE1364-2000 also says the same thing. + +However, the BNF clearly states that 0, 1, x and X are valid +output_symbol characters. The standard is self contradictory. So I +take it that x is allowed, as that is what Verilog-XL does. + + +* REPEAT LOOPS vs. REPEAT EVENT CONTROL + +There seems to be ambiguity in how code like this should be parsed:: + + repeat (5) @(posedge clk) ; + +There are two valid interpretations of this code, from the +IEEE1364-1995 standard. One looks like this:: + + procedural_timing_control_statement ::= + delay_or_event_control statement_or_null + + delay_or_event_control ::= + event_control + | repeat ( expression ) event_control + +If this interpretation is used, then the statement should +be executed after the 5th posedge of clk. However, there is also this +interpretation:: + + loop_statement ::= + repeat ( expression ) statement + +If *this* interpretation is used, then should be executed +5 times on the posedge of clk. The way the -1995 standard is written, +these are both equally valid interpretations of the example, yet they +produce very different results. The standard offers no guidance on how +to resolve this conflict, and the IEEE1364-2000 DRAFT does not improve +the situation. + +Practice suggests that a repeat followed by an event control should be +interpreted as a loop head, and this is what Icarus Verilog does, as +well as all the other major Verilog tools, but the standard does not +say this. + +* UNSIZED NUMERIC CONSTANTS ARE NOT LIMITED TO 32 BITS + +The Verilog standard allows Verilog implementations to limit the size +of unsized constants to a bit width of at least 32. That means that a +constant 17179869183 (36'h3_ffff_ffff) may overflow some compilers. In +fact, it is common to limit these values to 32bits. However, a +compiler may just as easily choose another width limit, for example +64bits. That value is equally good. + +However, it is not *required* that an implementation truncate at 32 +bits, and in fact Icarus Verilog does not truncate at all. It will +make the unsized constant as big as it needs to be to hold the value +accurately. This is especially useful in situations like this:: + + reg [width-1:0] foo = 17179869183; + +The programmer wants the constant to take on the width of the reg, +which in this example is parameterized. Since constant sizes cannot be +parameterized, the programmer ideally gives an unsized constant, which +the compiler then expands/contracts to match the l-value. + +Also, by choosing to not ever truncate, Icarus Verilog can handle code +written for a 64bit compiler as easily as for a 32bit compiler. In +particular, any constants that the user does not expect to be +arbitrarily truncated by his compiler will also not be truncated by +Icarus Verilog, no matter what that other compiler chooses as a +truncation point. + + +* UNSIZED EXPRESSIONS AS PARAMETERS TO CONCATENATION {} + +The Verilog standard clearly states in 4.1.14:: + + "Unsized constant numbers shall not be allowed in + concatenations. This is because the size of each + operand in the concatenation is needed to calculate + the complete size of the concatenation." + +So for example the expression {1'b0, 16} is clearly illegal. It +also stands to reason that {1'b0, 15+1} is illegal, for exactly the +same justification. What is the size of the expression (15+1)? +Furthermore, it is reasonable to expect that (16) and (15+1) are +exactly the same so far as the compiler is concerned. + +Unfortunately, Cadence seems to feel otherwise. In particular, it has +been reported that although {1'b0, 16} causes an error, {1'b0, 15+1} +is accepted. Further testing shows that any expression other than a +simple unsized constant is accepted there, even if all the operands of +all the operators that make up the expression are unsized integers. + +This is a semantic problem. Icarus Verilog doesn't limit the size of +integer constants. This is valid as stated in 2.5.1 Note 3:: + + "The number of bits that make up an unsized number + (which is a simple decimal number or a number without + the size specification) shall be *at*least* 32." + [emphasis added] + +Icarus Verilog will hold any integer constant, so the size will be as +large as it needs to be, whether that is 64bits, 128bits, or +more. With this in mind, what is the value of these expressions? + +:: + + {'h1_00_00_00_00} + {'h1 << 32} + {'h0_00_00_00_01 << 32} + {'h5_00_00_00_00 + 1} + +These examples show that the standard is justified in requiring that +the operands of concatenation have size. The dispute is what it takes +to cause an expression to have a size, and what that size is. +Verilog-XL claims that (16) does not have a size, but (15+1) does. The +size of the expression (15+1) is the size of the adder that is +created, but how wide is the adder when adding unsized constants? + +One might note that the quote from section 4.1.14 says "Unsized +*constant*numbers* shall not be allowed." It does not say "Unsized +expressions...", so arguably accepting (15+1) or even (16+0) as an +operand to a concatenation is not a violation of the letter of the +law. However, the very next sentence of the quote expresses the +intent, and accepting (15+1) as having a more defined size than (16) +seems to be a violation of that intent. + +Whatever a compiler decides the size is, the user has no way to +predict it, and the compiler should not have the right to treat (15+1) +any differently than (16). Therefore, Icarus Verilog takes the +position that such expressions are *unsized* and are not allowed as +operands to concatenations. Icarus Verilog will in general assume that +operations on unsized numbers produce unsized results. There are +exceptions when the operator itself does define a size, such as the +comparison operators or the reduction operators. Icarus Verilog will +generate appropriate error messages. + + +* MODULE INSTANCE WITH WRONG SIZE PORT LIST + +A module declaration like this declares a module that takes three ports:: + + module three (a, b, c); + input a, b, c; + reg x; + endmodule + +This is fine and obvious. It is also clear from the standard that +these are legal instantiations of this module:: + + three u1 (x,y,z); + three u2 ( ,y, ); + three u3 ( , , ); + three u4 (.b(y)); + +In some of the above examples, there are unconnected ports. In the +case of u4, the pass by name connects only port b, and leaves a and c +unconnected. u2 and u4 are the same thing, in fact, but using +positional or by-name syntax. The next example is a little less +obvious:: + + three u4 (); + +The trick here is that strictly speaking, the parser cannot tell +whether this is a list of no pass by name ports (that is, all +unconnected) or an empty positional list. If this were an empty +positional list, then the wrong number of ports is given, but if it is +an empty by-name list, it is an obviously valid instantiation. So it +is fine to accept this case as valid. + +These are more doubtful:: + + three u5(x,y); + three u6(,); + +These are definitely positional port lists, and they are definitely +the wrong length. In this case, the standard is not explicit about +what to do about positional port lists in module instantiations, +except that the first is connected to the first, second to second, +etc. It does not say that the list must be the right length, but every +example of unconnected ports used by-name syntax, and every example of +ordered list has the right size list. + +Icarus Verilog takes the (very weak) hint that ordered lists should be +the right length, and will therefore flag instances u5 and u6 as +errors. The IEEE1364 standard should be more specific one way or the +other. + +* UNKNOWN VALUES IN L-VALUE BIT SELECTS + +Consider this example:: + + reg [7:0] vec; + wire [4:0] idx = ; + [...] + vec[idx] = 1; + +So long as the value of idx is a valid bit select address, the +behavior of this assignment is obvious. However, there is no explicit +word in the standard as to what happens if the value is out of +range. The standard clearly states the value of an expression when the +bit-select or part select is out of range (the value is x) but does +not address the behavior when the expression is an l-value. + +Icarus Verilog will take the position that bit select expressions in +the l-value will select oblivion if it is out of range. That is, if +idx has a value that is not a valid bit select of vec, then the +assignment will have no effect. + + +* SCHEDULING VALUES IN LOGIC + +The interaction between blocking assignments in procedural code and +logic gates in gate-level code and expressions is poorly defined in +Verilog. Consider this example:: + + reg a; + reg b; + wire q = a & b; + + initial begin + a = 1; + b = 0; + #1 b = 1; + if (q !== 0) begin + $display("FAILED -- q changed too soon? %b", q); + $finish; + end + end + +This is a confusing situation. It is clear from the Verilog standard +that an assignment to a variable using a blocking assign causes the +l-value to receive the value before the assignment completes. This +means that a subsequent read of the assigned variable *must* read back +what was blocking-assigned. + +However, in the example above, the "wire q = a & b" expresses some +gate logic between a/b and q. The standard does not say whether a read +out of logic should read the value computed from previous assigns to +the input from the same thread. Specifically, when "a" and "b" are +assigned by blocking assignments, will a read of "q" get the computed +value or the existing value? + +In fact, existing commercial tools do it both ways. Some tools print +the FAILED message in the above example, and some do not. Icarus +Verilog does not print the FAILED message in the above example, +because the gate value change is *scheduled* when inputs are assigned, +but not propagated until the thread gives up the processor. + +Icarus Verilog chooses this behavior in order to filter out zero-width +pulses as early as possible. The implication of this is that a read of +the output of combinational logic will most likely *not* reflect the +changes in inputs until the thread that changed the inputs yields +execution. + + +* BIT AND PART SELECTS OF PARAMETERS + +Bit and part selects are supposed to only be supported on vector nets +and variables (wires, regs, etc.) However, it is common for Verilog +compilers to also support bit and part select on parameters. Icarus +Verilog also chooses to support bit and part selects on parameter +names, but we need to define what that means. + +A bit or a part select on a parameter expression returns an unsigned +value with a defined size. The parameter value is considered be a +constant vector of bits foo[X:0]. That is, zero based. The bit and +part selects operate from that assumption. + +Verilog 2001 adds syntax to allow the user to explicitly declare the +parameter range (i.e. parameter [5:0] foo = 9;) so Icarus Verilog will +(or should) use the explicitly declared vector dimensions to interpret +bit and part selects. + + +* EDGES OF VECTORS + +Consider this example:: + + reg [ 5:0] clock; + always @(posedge clock) [do stuff] + +The IEEE1364 standard clearly states that the @(posedge clock) looks +only at the bit clock[0] (the least significant bit) to search for +edges. It has been pointed out by some that Verilog XL instead +implements it as `@(posedge |clock)`: it looks for a rise in the +reduction or of the vector. Cadence Design Systems technical support +has been rumored to claim that the IEEE1364 specification is wrong, +but NC-Verilog behaves according to the specification, and thus +different from XL. + +Icarus Verilog, therefore, takes the position that the specification +is clear and correct, and it behaves as does NC-Verilog in this +matter. + + +* REAL VARIABLES IN $dumpoff DEAD-ZONES + +The IEEE1364 standard clearly states that in VCD files, the $dumpoff +section checkpoints all the dumped variables as X values. For reg and +wire bits/vectors, this obviously means 'bx values. Icarus Verilog +does this, for example:: + + $dumpoff + x! + x" + $end + +Real variables can also be included in VCD dumps, but it is not at +all obvious what is supposed to be dumped into the $dumpoff-$end +section of the VCD file. Verilog-XL dumps "r0 !" to set the real +variables to the dead-zone value of 0.0, whereas other tools, such as +ModelTech, ignore real variables in this section. + +For example (from XL):: + + $dumpoff + r0 ! + r0 " + $end + +Icarus Verilog dumps NaN values for real variables in the +$dumpoff-$end section of the VCD file. The NaN value is the IEEE754 +equivalent of an unknown value, and so better reflects the unknown +(during the dead zone) status of the variable, like this:: + + $dumpoff + rNaN ! + rNaN " + $end + +It turns out that NaN is conventionally accepted by scanf functions, +and viewers that support real variables support NaN values. So while +the IEEE1364 doesn't require this behavior, and given the variety that +already seems to exist amongst VCD viewers in the wild, this behavior +seems to be acceptable according to the standard, is a better mirror +of 4-value behavior in the dead zone, and appears more user friendly +when viewed by reasonable viewers. diff --git a/_sources/developer/guide/misc/index.rst.txt b/_sources/developer/guide/misc/index.rst.txt new file mode 100644 index 0000000000..8a0f5083ca --- /dev/null +++ b/_sources/developer/guide/misc/index.rst.txt @@ -0,0 +1,10 @@ + +Miscellaneous +============= + +.. toctree:: + :maxdepth: 1 + + ieee1364-notes + swift + xilinx-hint diff --git a/_sources/developer/guide/misc/swift.rst.txt b/_sources/developer/guide/misc/swift.rst.txt new file mode 100644 index 0000000000..7f5c4d9498 --- /dev/null +++ b/_sources/developer/guide/misc/swift.rst.txt @@ -0,0 +1,68 @@ + +Swift Model Support (Preliminary) +================================= + + Copyright 2003-2024 Stephen Williams + + NOTE: SWIFT support does not work yet, these are provisional + instructions, intended to show what's supposed to happen when I get + it working. + +Icarus Verilog support for SWIFT models is based on the LMTV interface +module from Synopsys. This module is normally distributed along with +the SWIFT models proper. This module can be linked with Icarus Verilog +via the cadpli compatibility object. (See cadpli.txt.) + +* Preliminaries + +First, you need the LMC_HOME environment variable set to point to the +installed directory for your SWIFT software. This setup is documented +in your SWIFT model documentation. + +* Compilation + +When compiling your Verilog design to include a SWIFT model, you need +to include wrappers for the model you intend to use. You may choose to +use ncverilog or verilogxl compatible wrappers, they work the +same. Locate your smartmodel directory, and include it in your command +file like so:: + + +libdir+.../smartmodel/sol/wrappers/verilogxl + +The wrappers directory includes Verilog modules that wrap your SWIFT +module, and with this +libdir+ statement in your command file, the +Icarus Verilog compiler will be able to locate these wrappers. The +wrappers in turn invoke the $lm_model system tasks that are the LMTV +support for your model. + + NOTE: This example uses the solaris directory of VerilogXL support + files as a source of wrappers. The files of interest, however, are + written in Verilog and are identical for all supported platforms, so + long as you choose the verilogxl or ncverilog files. + +* Execution + +After your simulation is compiled, run the simulation with the vvp +command, like this:: + + % vvp -mcadpli a.out -cadpli=$LMC_HOME/lib/x86_linux.lib/swiftpli.so:swift_boot + +What this command line means is:: + + -mcadpli + Include the cadpli compatibility module + + a.out + This is your compiled vvp file + + -cadpli=$LMC_HOME/lib/x86_linux.lib/swiftpli.so:swift_boot + This tells the cadpli module to load the swiftpli.so + shared object, and boot it. This is code that comes with + your SWIFT modules, and provides the generic SWIFT + capabilities (lm_* system tasks) needed by the module + itself. + +Once you start the vvp command, the SWIFT infrastructure will be +initialized as part of the simulation setup, and all should work +normally from here. + diff --git a/_sources/developer/guide/misc/xilinx-hint.rst.txt b/_sources/developer/guide/misc/xilinx-hint.rst.txt new file mode 100644 index 0000000000..4e58e9ef51 --- /dev/null +++ b/_sources/developer/guide/misc/xilinx-hint.rst.txt @@ -0,0 +1,113 @@ + +Xilinx Hint +=========== + +For those of you who wish to use Icarus Verilog, in combination with +the Xilinx back end (Foundation or Alliance), it can be done. I have +run some admittedly simple (2300 equivalent gates) designs through this +setup, targeting a Spartan XCS10. + +Verilog: +-------- + +Older versions of Icarus Verilog (like 19990814) couldn't synthesize +logic buried in procedural (flip-flop) assignment. Newer versions +(like 20000120) don't have this limitation. + +Procedural assignments have to be given one at a time, to be +"found" by xnfsyn. Say + +:: + + always @ (posedge Clk) Y = newY; + always @ (posedge Clk) Z = newZ; + +rather than + +:: + + always @ (posedge Clk) begin + Y = newY; + Z = newZ; + end + +Steve's xnf.txt covers most buffer and pin constructs, but I had reason +to use a global clock net not connected to an input pin. The standard +Verilog for a buffer, combined with a declaration to turn that into a +BUFG, is:: + + buf BUFG( your_output_here, your_input_here ); + $attribute(BUFG,"XNF-LCA","BUFG:O,I") + +I use post-processing on my .xnf files to add "FAST" attributes to +output pins. + +Running ivl: +------------ + +The -F switches are important. The following order seems to robustly +generate valid XNF files, and is used by "verilog -X":: + + -Fsynth -Fnodangle -Fxnfio + +Generating .pcf files: +---------------------- + +The ngdbuild step seems to lose pin placement information that ivl +puts in the XNF file. Use xnf2pcf to extract this information to +a .pcf file, which the Xilinx place-and-route software _will_ pay +attention to. Steve says he now makes that information available +in an NCF file, with -fncf=, but I haven't tested that. + +Running the Xilinx back end: + +You can presumably use the GUI, but that doesn't fit in Makefiles :-). +Here is the command sequence in pseudo-shell-script:: + + ngdbuild -p $part $1.xnf $1.ngd + map -p $part -o map.ncd $1.ngd + xnf2pcf <$1.xnf >$1.pcf # see above + par -w -ol 2 -d 0 map.ncd $1.ncd $1.pcf + bitgen_flags = -g ConfigRate:SLOW -g TdoPin:PULLNONE -g DonePin:PULLUP \ + -g CRC:enable -g StartUpClk:CCLK -g SyncToDone:no \ + -g DoneActive:C1 -g OutputsActive:C3 -g GSRInactive:C4 \ + -g ReadClk:CCLK -g ReadCapture:enable -g ReadAbort:disable + bitgen $1.ncd -l -w $bitgen_flags + +The Xilinx software has diarrhea of the temp files (14, not including +.xnf, .pcf, .ngd, .ncd, and .bit), so this sequence is best done in a +dedicated directory. Note in particular that map.ncd is a generic name. + +I had reason to run this remotely (and transparently within a Makefile) +via ssh. I use the gmake rule:: + + %.bit : %.xnf + ssh -x -a -o 'BatchMode yes' ${ALLIANCE_HOST} \ + remote_alliance ${REMOTE_DIR} $(basename $@) 2>&1 < $< + scp ${ALLIANCE_HOST}:${REMOTE_DIR}/$@ . + +and the remote_alliance script (on ${ALLIANCE_HOST}):: + + /bin/csh + cd $1 + cat >! $2.xnf + xnf2pcf <$2.xnf >! $2.pcf + ./backend $2 + +There is now a "Xilinx on Linux HOWTO" at http://www.polybus.com/xilinx_on_linux.html +I haven't tried this yet, it looks interesting. + +Downloading: +------------ + +I use the XESS (http://www.xess.com/) XSP-10 development board, which +uses the PC parallel (printer) port for downloading and interaction +with the host. They made an old version of their download program +public domain, posted it at http://www.xess.com/FPGA/xstools.zip , +and now there is a Linux port at ftp://ftp.microux.com/pub/pilotscope/xstools.tar.gz . + +The above hints are based on my experience with Foundation 1.5 on NT +(gack) and Alliance 2.1i on Solaris. Your mileage may vary. Good luck! + + - Larry Doolittle August 19, 1999 + updated February 1, 2000 diff --git a/_sources/developer/guide/tgt-vvp/tgt-vvp.rst.txt b/_sources/developer/guide/tgt-vvp/tgt-vvp.rst.txt new file mode 100644 index 0000000000..bc2b863abf --- /dev/null +++ b/_sources/developer/guide/tgt-vvp/tgt-vvp.rst.txt @@ -0,0 +1,36 @@ + +The VVP Target +============== + +Symbol Name Conventions +----------------------- + +There are some naming conventions that the vvp target uses for +generating symbol names. + +* wires and regs + +Nets and variables are named V_ where is the +full hierarchical name of the signal. + +* Logic devices + +Logic devices (and, or, buf, bufz, etc.) are named L_. In +this case the symbol is attached to a functor that is the output of +the logic device. + + +General Functor Web Structure +----------------------------- + +The net of gates, signals and resolvers is formed from the input +design. The basic structure is wrapped around the nexus, which is +represented by the ivl_nexus_t. + +Each nexus represents a resolved value. The input of the nexus is fed +by a single driver. If the nexus in the design has multiple drivers, +the drivers are first fed into a resolver (or a tree of resolvers) to +form a single output that is the nexus. + +The nexus, then, feeds its output to the inputs of other gates, or to +the .net objects in the design. diff --git a/_sources/developer/guide/vpi/index.rst.txt b/_sources/developer/guide/vpi/index.rst.txt new file mode 100644 index 0000000000..77a0754c4f --- /dev/null +++ b/_sources/developer/guide/vpi/index.rst.txt @@ -0,0 +1,9 @@ + +VPI in Icarus Verilog +===================== + +.. toctree:: + :maxdepth: 1 + + vpi + va_math diff --git a/_sources/developer/guide/vpi/va_math.rst.txt b/_sources/developer/guide/vpi/va_math.rst.txt new file mode 100644 index 0000000000..ac63a94943 --- /dev/null +++ b/_sources/developer/guide/vpi/va_math.rst.txt @@ -0,0 +1,100 @@ + +Verilog-A math library +====================== + +License. +-------- + + Verilog-A math library built for Icarus Verilog + https://github.com/steveicarus/iverilog/ + + Copyright (C) 2007-2024 Cary R. (cygcary@yahoo.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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Standard Verilog-A Mathematical Functions. +------------------------------------------ + +The va_math VPI module implements all the standard math functions provided +by Verilog-A as Verilog-D system functions. The names are the same except +like all Verilog-D system functions the name must be prefixed with a '$'. +For reference the functions are:: + + $ln(x) -- Natural logarithm + $log10(x) -- Decimal logarithm + $exp(x) -- Exponential + $sqrt(x) -- Square root + $min(x,y) -- Minimum + $max(x,y) -- Maximum + $abs(x) -- Absolute value + $floor(x) -- Floor + $ceil(x) -- Ceiling + $pow(x,y) -- Power (x**y) + $sin(x) -- Sine + $cos(x) -- Cosine + $tan(x) -- Tangent + $asin(x) -- Arc-sine + $acos(x) -- Arc-cosine + $atan(x) -- Arc-tangent + $atan2(y,x) -- Arc-tangent of y/x + $hypot(x,y) -- Hypotenuse (sqrt(x**2 + y**2)) + $sinh(x) -- Hyperbolic sine + $cosh(x) -- Hyperbolic cosine + $tanh(x) -- Hyperbolic tangent + $asinh(x) -- Arc-hyperbolic sine + $acosh(x) -- Arc-hyperbolic cosine + $atanh(x) -- Arc-hyperbolic tangent + +The only limit placed on the x and y arguments by the library is that they +must be numbers (not constant strings). The underlying C library controls +any other limits placed on the arguments. Most libraries return +-Inf or +NaN for results that cannot be represented with real numbers. All functions +return a real result. + +Standard Verilog-A Mathematical Constants. +------------------------------------------ + +The Verilog-A mathematical constants can be accessed by including the +"constants.vams" header file. It is located in the standard include +directory. Recent version of Icarus Verilog (0.9.devel) automatically +add this directory to the end of the list used to find include files. +For reference the mathematical constants are:: + + `M_PI -- Pi + `M_TWO_PI -- 2*Pi + `M_PI_2 -- Pi/2 + `M_PI_4 -- Pi/4 + `M_1_PI -- 1/Pi + `M_2_PI -- 2/Pi + `M_2_SQRTPI -- 2/sqrt(Pi) + `M_E -- e + `M_LOG2E -- log base 2 of e + `M_LOG10E -- log base 10 of e + `M_LN2 -- log base e of 2 + `M_LN10 -- log base e of 10 + `M_SQRT2 -- sqrt(2) + `M_SQRT1_2 -- 1/sqrt(2) + +Using the Library. +------------------ + +Just add "-m va_math" to your iverilog command line/command file and +\`include the "constants.vams" file as needed. + +Thanks +------ + +I would like to thank Larry Doolittle for his suggestions and +Stephen Williams for developing Icarus Verilog. diff --git a/_sources/developer/guide/vpi/vpi.rst.txt b/_sources/developer/guide/vpi/vpi.rst.txt new file mode 100644 index 0000000000..89c73c0ff4 --- /dev/null +++ b/_sources/developer/guide/vpi/vpi.rst.txt @@ -0,0 +1,50 @@ + +VPI Modules in Icarus Verilog +================================ + +The VPI interface for Icarus Verilog works by creating from a +collection of PLI applications a single vpi module. The vpi module +includes compiled code for the applications linked together (with any +other libraries that the applications need) into a module with two +exported symbols, the vpip_set_callback function and the +vlog_startup_routines array. + +The product that wishes to invoke the module (normally at run time) loads +the module, locates and calls the vpip_set_callback function to pass the +the module a jump table that allows the module to access the VPI routines +implemented by the product, then locates the vlog_startup_routines table +and calls all the startup routines contained in that table. It is possible +for a product to link with many modules. In that case, all the modules are +linked in and startup routines are called in order. + +The product that uses vpi modules uses the environment variable +VPI_MODULE_PATH as a ':' separated list of directories. This is the +module search path. When a module is specified by name (using whatever +means the product supports) the module search path is scanned until +the module is located. + +The special module names "system.vpi", "v2005_math.vpi", "v2009.vpi", +and "va_math.vpi" are part of the core Icarus Verilog distribution and +include implementations of the standard system tasks/functions. The +additional special module names "vhdl_sys.vpi" and "vhdl_textio.vpi" +include implementations of private functions used to support VHDL. + +Compiling A VPI Module +---------------------- + +See the documentation under: :doc:`Using VPI <../../../usage/vpi>` + +Tracing VPI Use +--------------- + +The vvp command includes the ability to trace VPI calls. This is +useful if you are trying to debug a problem with your code. To +activate tracing simply set the VPI_TRACE environment variable, with +the path to a file where trace text gets written. For example:: + + setenv VPI_TRACE /tmp/foo.txt + +This tracing is pretty verbose, so you don't want to run like this +normally. Also, the format of the tracing messages will change +according to my needs (and whim) so don't expect to be able to parse +it in software. diff --git a/_sources/developer/guide/vvp/debug.rst.txt b/_sources/developer/guide/vvp/debug.rst.txt new file mode 100644 index 0000000000..bef2f68296 --- /dev/null +++ b/_sources/developer/guide/vvp/debug.rst.txt @@ -0,0 +1,19 @@ + +Debug Aids For VVP +================== + +Debugging vvp can be fiendishly difficult, so there are some built in +debugging aids. These are enabled by setting the environment variable +VVP_DEBUG to the path to an output file. Then, various detailed debug +tools can be enabled as described below. + +* .resolv + +The .resolv can print debug information along with a label by +specifying the debug output label on the .resolv line:: + + .resolv tri$

+ + Add a directory to the include path. Normally, only "." is + in the search path. The -I flag causes other directories + to be searched for a named file. There may be as many -I + flags as needed. + +* -L + + Generate \`line directives. The ivl compiler understands + these directives and uses them to keep track of the + current line of the original source file. This makes error + messages more meaningful. + +* -o + + Send the output to the named file, instead of to standard + output. + +* -v + + Print version and copyright information before processing + input files. + +* -V + + Print version and copyright information, then exit WITHOUT + processing any input files. + +Flags File +---------- + +A flags file contains flags for use by ivlpp. This is a convenient way +for programs to pass complex sets of flags to the ivlpp program. + +Blank lines and lines that start with "#" are ignored. The latter can +be used as comment lines. All other lines are flag lines. Leading and +trailing white space are removed before the lines are interpreted. + +Other lines have the simple format:: + + : + +The colon character separates a key from the value. The supported +keys, with their corresponding values, are: + +* D:name= + + This is exactly the same as the "-Dname=" described above. + +* I: + + This is exactly the same as "-I". + +* relative include: + + The can be "true" or "false". This enables "relative + includes" nesting behavior. + +* vhdlpp: + + Give the path to the vhdlpp program. This program is used to + process VHDL input files. + +Locating Included Files +----------------------- + +The ivlpp preprocessor implements the \`include directives by +substituting the contents of the included file in place of the line +with the \`include directive. The name that the programmer specifies is +a file name. Normally, the preprocessor looks in the current working +directory for the named file. However, the `-I` flags can be used to +specify a path of directories to search for named include files. The +current directory will be searched first, followed by all the include +directories in the order that the -I flag appears. + +The exception to this process is include files that have a name that +starts with the '/' character. These file names are `rooted names` +and must be in the rooted location specified. + + +Generated Line Directives +------------------------- + +Compilers generally try to print along with their error messages the +file and line number where the error occurred. Icarus Verilog is no +exception. However, if a separate preprocessor is actually selecting +and opening files, then the line numbers counted by the compiler +proper will not reflect the actual line numbers in the source file. + +To handle this situation, the preprocessor can generate line +directives. These directives are lines of the form:: + + `line + +where is the file name in double-quotes and is the line +number in the file. The parser changes the filename and line number +counters in such a way that the next line is line number in +the file named . For example:: + + `line 6 "foo.vl" 0 + // I am on line 6 in file foo.vl. + +The preprocessor generates a \`line directive every time it switches +files. That includes starting an included file (\`line 1 "foo.vlh" 1) or +returning to the including file. + diff --git a/_sources/usage/reporting_issues.rst.txt b/_sources/usage/reporting_issues.rst.txt new file mode 100644 index 0000000000..04fa405232 --- /dev/null +++ b/_sources/usage/reporting_issues.rst.txt @@ -0,0 +1,76 @@ + +Reporting Issues +================ + +The developers of and contributers to Icarus Verilog use github to track +issues and to create patches for the product. If you believe you have found a +problem, use the Issues tracker at the +`Icarus Verilog github page `_. + +You may browse the bugs database for existing +bugs that may be related to yours. You might find that your bug has +already been fixed in a later release or snapshot. If that's the case, +then you are set. + +On the main page, you will find a row of selections near the top. Click the +`Issues `_ link to get to the +list of issues, open and closed. You will find a friendly green button where +you can create a new issue. You will be asked to create a title for your +issue, and to write a detailed description of your issue. Please include +enough information that anyone who sees your issue can understand and +reproduce it. + +Good Issue Reporting +-------------------- + +Before an error can be fixed, one needs to understand what the problem +is. Try to explain what is wrong and why you think it is wrong. Please +try to include sample code that demonstrates the problem. + +One key characteristic of a well reported issue is a small sample program that +demonstrates the issue. The smaller the better. No developer wants to wade +through hundreds of lines of working Verilog to find the few lines that cause +trouble, so if you can get it down to a 10 line sample program, then your +issue will be far more likely to be addressed. + +Also, include the command line you use to invoke the compiler. For +example:: + + iverilog -o foo.out -tvvp foo.v + iverilog foo.vl -s starthere + +Be prepared to have a conversation about your issue. More often then you would +expect, the issue turns out to be a bug in your program, and the person +looking into your issue may point out a bug in your code. You learn something, +and we all win. We are not always correct, though, so if we are incorrect, +help us see our error, if that's appropriate. If we don't understand what your +issue is, we will label your issue with a "Need info" label, and if we never +hear from you again, your issue may be closed summarily. + +If you can submit a complete, working program that we can use in the +regression test suite, then that is the best. Check out the existing tests in +the regression test suite to see how they are structured. If you have a +complete test that can go into the test suite, then that saves everyone a lot +of grief, and again you increase the odds that your issue will be addressed. + +How To Create A Pull Request +---------------------------- + +Bug reports with patches/PRs are very welcome. Please also add a new test case in the regression test suite to prevent the bug from reappearing. + +If you are editing the source, you should be using the latest +version from git. Please see the developer documentation for more +detailed instructions -- :doc:`Getting Started as a Contributer ` . + +COPYRIGHT ISSUES + +Icarus Verilog is Copyright (c) 1998-2024 Stephen Williams except +where otherwise noted. Minor patches are covered as derivative works +(or editorial comment or whatever the appropriate legal term is) and +folded into the rest of ivl. However, if a submission can reasonably +be considered independently copyrightable, it's yours and I encourage +you to claim it with appropriate copyright notices. This submission +then falls under the "otherwise noted" category. + +I must insist that any copyright material submitted for inclusion +include the GPL license notice as shown in the rest of the source. diff --git a/_sources/usage/simulation.rst.txt b/_sources/usage/simulation.rst.txt new file mode 100644 index 0000000000..5a0c39498c --- /dev/null +++ b/_sources/usage/simulation.rst.txt @@ -0,0 +1,495 @@ + +Simulation Using Icarus Verilog +=============================== + +Simulation is the process of creating models that mimic the behavior of the +device you are designing (simulation models) and creating models to exercise +the device (test benches). The simulation model need not reflect any +understanding of the underlying technology, and the simulator need not know +that the design is intended for any specific technology. + +The Verilog simulator, in fact, is usually a different program than the +synthesizer. It may even come from a different vendor. The simulator need not +know of or generate netlists for the target technology, so it is possible to +write one simulator that can be used to model designs intended for a wide +variety of technologies. A synthesizer, on the other hand, does need to know a +great deal about the target technology in order to generate efficient +netlists. Synthesizers are often technology specific and come from vendors +with specialized knowledge, whereas simulators are more general purpose. + +Simulation models and test benches, therefore, can use the full range of +Verilog features to model the intended design as clearly as possible. This is +the time to test the algorithms of the design using language that is +relatively easy for humans to read. The simulator, along with the test bench, +can test that the clearly written model really does behave as intended, and +that the intended behavior really does meet expectations. + +The test benches model the world outside the design, so they are rarely +destined for real hardware. They are written in Verilog simply as a matter of +convenience, and sometimes they are not written in Verilog at all. The test +benches are not throw-away code either, as they are used to retest the device +under test as it is transformed from a simulation model to a synthesizeable +description. + +Compilation and Elaboration +--------------------------- + +Simulation of a design amounts to compiling and executing a program. The +Verilog source that represents the simulation model and the test bench is +compiled into an executable form and executed by a simulation +engine. Internally, Icarus Verilog divides the compilation of program source +to an executable form into several steps, and basic understanding of these +steps helps understand the nature of failures and errors. The first step is +macro preprocessing, then compilation, elaboration, optional optimizations and +finally code generation. The boundary between these steps is often blurred, +but this progression remains a useful model of the compilation process. + +The macro preprocessing step performs textual substitutions of macros defined +with "\`define" statements, textual inclusion with "\`include" statements, and +conditional compilation by "\`ifdef" and "\`ifndef" statements. The +macropreprocessor for Icarus Verilog is internally a separate program that can +be accessed independently by using the "-E" flag to the "iverilog" command, +like so:: + + % iverilog -E -o out.v example.v + +This command causes the input Verilog file "example.v" to be preprocessed, and +the output, a Verilog file without preprocessor statements, written into +"out.v". The "\`include" and "\`ifdef" directives in the input file are interpreted, +and defined macros substituted, so that the output, a single file, is the same +Verilog but with the preprocessor directives gone. All the explicitly +specified source files are also combined by the preprocessor, so that the +preprocessed result is a single Verilog stream. + +Normally, however, the "-E" flag is not used and the preprocessed Verilog is +instead sent directly to the next step, the compiler. The compiler core takes +as input preprocessed Verilog and generates an internal parsed form. The +parsed form is an internal representation of the Verilog source, in a format +convenient for further processing, and is not accessible to the user. + +The next step, elaboration, takes the parsed form, chooses the root modules, +and instantiates (makes *instances* of) those roots. The root instances may +contain instances of other modules, which may in turn contain instances of yet +other modules. The elaboration process creates a hierarchy of module instances +that ends with primitive gates and statements. + +Note that there is a difference between a module and a module instance. A +module is a type. It is a description of the contents of module instances that +have its type. When a module is instantiated within another module, the module +name identifies the type of the instance, and the instance name identifies the +specific instance of the module. There can be many instances of any given +module. + +Root modules are a special case, in that the programmer does not give them +instance names. Instead, the instance names of root modules are the same as +the name of the module. This is valid because, due to the nature of the +Verilog syntax, a module can be a root module only once, so the module name +itself is a safe instance name. + +Elaboration creates a hierarchy of scopes. Each module instance creates a new +scope within its parent module, with each root module starting a +hierarchy. Every module instance in the elaborated program has a unique scope +path, a hierarchical name, that starts with its root scope and ends with its +own instance name. Every named object, including variables, parameters, nets +and gates, also has a hierarchical name that starts with a root scope and ends +with its own base name. The compiler uses hierarchical names in error messages +generated during or after elaboration, so that erroneous items can be +completely identified. These hierarchical names are also used by waveform +viewers that display waveform output from simulations. + +The elaboration process creates from the parsed form the scope hierarchy +including the primitive objects within each scope. The elaborated design then +is optimized to reduce it to a more optimal, but equivalent design. The +optimization step takes the fully elaborated design and transforms it to an +equivalent design that is smaller or more efficient. These optimizations are, +for example, forms of constant propagation and dead code elimination. Useless +logic is eliminated, and constant expressions are pre-calculated. The +resulting design behaves as if the optimizations were not performed, but is +smaller and more efficient. The elimination (and spontaneous creation) of +gates and statements only affects the programmer when writing VPI modules, +which through the API have limited access to the structures of the design. + +Finally, the optimized design, which is still in an internal form not +accessible to users, is passed to a code generator that writes the design into +an executable form. For simulation, the code generator is selected to generate +the vvp format--a text format that can be executed by the simulation +engine. Other code generators may be selected by the Icarus Verilog user, even +third party code generators, but the vvp code generator is the default for +simulation purposes. + +Making and Using Libraries +-------------------------- + +Although simple programs may be written into a single source file, this gets +inconvenient as the designs get larger. Also, writing the entire program into +a single file makes it difficult for different programs to share common +code. It therefore makes sense to divide large programs into several source +files, and to put generally useful source code files somewhere accessible to +multiple designs. + +Once the program is divided into many files, the compiler needs to be told how +to find the files of the program. The simplest way to do that is to list the +source files on the command line or in a command file. This is for example the +best way to divide up and integrate test bench code with the simulation model +of the device under test. + +The Macro Preprocessor +^^^^^^^^^^^^^^^^^^^^^^ + +Another technique is to use the macro preprocessor to include library files +into a main file. The `include` directive takes the name of a source file to +include. The preprocessor inserts the entire contents of the included file in +place of the `include` directive. The preprocessor normally looks in the +current working directory (the current working directory of the running +compiler, and not the directory where the source file is located) for the +included file, but the "-I" switch to "iverilog" can add directories to the +search locations list. :: + + % iverilog -I/directory/to/search example.v + +It is common to create include directories shared by a set of programs. The +preprocessor `include` directive can be used by the individual programs to +include the source files that it needs. + +The preprocessor method of placing source code into libraries is general +(arbitrary source code can be placed in the included files) but is static, in +the sense that the programmer must explicitly include the desired library +files. The automatic module library is a bit more constrained, but is +automatic. + +Automatic Module Libraries +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A common use for libraries is to store module definitions that may be of use +to a variety of programs. If modules are divided into a single module per +file, and the files are named appropriately, and the compiler is told where to +look, then the compiler can automatically locate library files when it finds +that a module definition is missing. + +For this to work properly, the library files must be Verilog source, they +should contain a single module definition, and the files must be named after +the module they contain. For example, if the module "AND2" is a module in the +library, then it belongs in a file called "AND2.v" and that file contains only +the "AND2" module. A library, then, is a directory that contains properly +named and formatted source files. :: + + % iverilog -y/library/to/search example.v + +The "-y" flag to "iverilog" tells the compiler to look in the specified +directory for library modules whenever the program instantiates a module that +is not otherwise defined. The programmer may include several "-y" flags on the +command line (or in a command file) and the compiler will search each +directory in order until an appropriate library file is found to resolve the +module. + +Once a module is defined, either in the program or by reading a library +module, the loaded definition is used from then on within the program. If the +module is defined within a program file or within an included file, then the +included definition is used instead of any library definition. If a module is +defined in multiple libraries, then the first definition that the compiler +finds is used, and later definitions are never read. + +Icarus Verilog accesses automatic libraries during elaboration, after it has +already preprocessed and parsed the non-library source files. Modules in +libraries are not candidates for root modules, and are not even parsed unless +they are instantiated in other source files. However, a library module may +reference other library modules, and reading in a library module causes it to +be parsed and elaborated, and further library references resolved, just like a +non-library module. The library lookup and resolution process iterates until +all referenced modules are resolved, or known to be missing from the +libraries. + +The automatic module library technique is useful for including vendor or +technology libraries into a program. Many EDA vendors offer module libraries +that are formatted appropriately; and with this technique, Icarus Verilog can +use them for simulation. + +Advanced Command Files +---------------------- + +Command files were mentioned in the "Getting Started" chapter, but only +briefly. In practice, Verilog programs quickly grow far beyond the usefulness +of simple command line options, and even the macro preprocessor lacks the +flexibility to combine source and library modules according to the advancing +development process. + +The main contents of a command file is a list of Verilog source files. You can +name in a command file all the source files that make up your design. This is +a convenient way to collect together all the files that make up your +design. Compiling the design can then be reduced to a simple command line like +the following:: + + % iverilog -c example.cf + +The command file describes a configuration. That is, it lists the specific +files that make up your design. It is reasonable, during the course of +development, to have a set of different but similar variations of your +design. These variations may have different source files but also many common +source files. A command file can be written for each variation, and each +command file lists the source file names used by each variation. + +A configuration may also specify the use of libraries. For example, different +configurations may be implementations for different technologies so may use +different parts libraries. To make this work, command files may include "-y" +statements. These work in command files exactly how they work on "iverilog" +command line. Each "-y" flag is followed by a directory name, and the +directories are searched for library modules in the order that they are listed +in the command file. + +The include search path can also be specified in configuration files with +"+incdir+" tokens. These tokens start with the "+incdir+" string, then +continue with directory paths, separated from each other with "+" characters +(not spaces) for the length of the line. + +Other information can be included in the command file. See the section Command +File Format for complete details on what can go in a command file. + +Input Data at Runtime +--------------------- + +Often, it is useful to compile a program into an executable simulation, then +run the simulation with various inputs. This requires some means to pass data +and arguments to the compiled program each time it is executed. For example, +if the design models a micro-controller, one would like to run the compiled +simulation against a variety of different ROM images. + +There are a variety of ways for a Verilog program to get data from the outside +world into the program at run time. Arguments can be entered on the command +line, and larger amounts of data can be read from files. The simplest method +is to take arguments from the command line. + +Consider this running example of a square root calculator + +.. code-block:: verilog + + module sqrt32(clk, rdy, reset, x, .y(acc)); + input clk; + output rdy; + input reset; + + input [31:0] x; + output [15:0] acc; + + // acc holds the accumulated result, and acc2 is + // the accumulated square of the accumulated result. + reg [15:0] acc; + reg [31:0] acc2; + + // Keep track of which bit I'm working on. + reg [4:0] bitl; + wire [15:0] bit = 1 << bitl; + wire [31:0] bit2 = 1 << (bitl << 1); + + // The output is ready when the bitl counter underflows. + wire rdy = bitl[4]; + + // guess holds the potential next values for acc, + // and guess2 holds the square of that guess. + wire [15:0] guess = acc | bit; + wire [31:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1); + + task clear; + begin + acc = 0; + acc2 = 0; + bitl = 15; + end + endtask + + initial clear; + + always @(reset or posedge clk) + if (reset) + clear; + else begin + if (guess2 <= x) begin + acc <= guess; + acc2 <= guess2; + end + bitl <= bitl - 1; + end + + endmodule + +One could write the test bench as a program that passes a representative set +of input values into the device and checks the output result. However, we can +also write a program that takes on the command line an integer value to be +used as input to the device. We can write and compile this program, then pass +different input values on the run time command line without recompiling the +simulation. + +This example demonstrates the use of the "$value$plusargs" to access command +line arguments of a simulation + +.. code-block:: verilog + + module main; + + reg clk, reset; + reg [31:0] x; + wire [15:0] y; + wire rdy; + + sqrt32 dut (clk, rdy, reset, x, y); + + always #10 clk = ~clk; + + initial begin + clk = 0; + reset = 1; + + if (! $value$plusargs("x=%d", x)) begin + $display("ERROR: please specify +x= to start."); + $finish; + end + + #35 reset = 0; + + wait (rdy) $display("y=%d", y); + $finish; + end // initial begin + + endmodule // main + +The "$value$plusargs" system function takes a string pattern that describes +the format of the command line argument, and a reference to a variable that +receives the value. The "sqrt_plusargs" program can be compiled and executed +like this:: + + % iverilog -osqrt_plusargs.vvp sqrt_plusargs.v sqrt.v + % vvp sqrt_plusargs.vvp +x=81 + y= 9 + +Notice that the "x=%d" string of the "$value$plusargs" function describes the +format of the argument. The "%d" matches a decimal value, which in the sample +run is "81". This gets assigned to "x" by the "$value$plusargs" function, +which returns TRUE, and the simulation continues from there. + +If two arguments have to be passed to the testbench then the main module would +be modified as follows + +.. code-block:: verilog + + module main; + + reg clk, reset; + reg [31:0] x; + reg [31:0] z; + wire [15:0] y1,y2; + wire rdy1,rdy2; + + sqrt32 dut1 (clk, rdy1, reset, x, y1); + sqrt32 dut2 (clk, rdy2, reset, z, y2); + + always #10 clk = ~clk; + + initial begin + clk = 0; + reset = 1; + + if (! $value$plusargs("x=%d", x)) begin + $display("ERROR: please specify +x= to start."); + $finish; + end + + if (! $value$plusargs("z=%d", z)) begin + $display("ERROR: please specify +z= to start."); + $finish; + end + + + #35 reset = 0; + + wait (rdy1) $display("y1=%d", y1); + wait (rdy2) $display("y2=%d", y2); + $finish; + end // initial begin + + endmodule // main + +and the "sqrt_plusargs" program would be compiled and executed as follows:: + + % iverilog -osqrt_plusargs.vvp sqrt_plusargs.v sqrt.v + % vvp sqrt_plusargs.vvp +x=81 +z=64 + y1= 9 + y2= 8 + +In general, the "vvp" command that executes the compiled simulation takes a +few predefined argument flags, then the file name of the simulation. All the +arguments after the simulation file name are extended arguments to "vvp" and +are passed to the executed design. Extended arguments that start with a "+" +character are accessible through the "$test$plusargs" and "$value$plusargs" +system functions. Extended arguments that do not start with a "+" character +are only accessible to system tasks and functions written in C using the VPI. + +In the previous example, the program pulls the argument from the command line, +assigns it to the variable "x", and runs the sqrt device under test with that +value. This program can take the integer square root of any single value. Of +course, if you wish to test with a large number of input values, executing the +program many times may become tedious. + +Another technique would be to put a set of input values into a data file, and +write the test bench to read the file. We can then edit the file to add new +input values, then rerun the simulation without compiling it again. The +advantage of this technique is that we can accumulate a large set of test +input values, and run the lot as a batch. + +This example + +.. code-block:: verilog + + module main; + + reg clk, reset; + reg [31:0] data[4:0]; + reg [31:0] x; + wire [15:0] y; + wire rdy; + + sqrt32 dut (clk, rdy, reset, x, y); + + always #10 clk = ~clk; + + integer i; + initial begin + /* Load the data set from the hex file. */ + $readmemh("sqrt.hex", data); + for (i = 0 ; i <= 4 ; i = i + 1) begin + clk = 0; + reset = 1; + + x = data[i]; + + #35 reset = 0; + + wait (rdy) $display("y=%d", y); + end + $finish; + end // initial begin + + endmodule // main + +demonstrates the use of "$readmemh" to read data samples from a file into a +Verilog array. Start by putting into the file "sqrt.hex" the numbers:: + + 51 + 19 + 1a + 18 + 1 + +Then run the simulation with the command sequence:: + + % iverilog -osqrt_readmem.vvp sqrt_readmem.vl sqrt.vl + % vvp sqrt_readmem.vvp + y= 9 + y= 5 + y= 5 + y= 4 + y= 1 + +It is easy enough to change this program to work with larger data sets, or to +change the "data.hex" file to contain different data. This technique is also +common for simulating algorithms that take in larger data sets. One can extend +this idea slightly by using a "$value$plusargs" statement to select the file +to read. diff --git a/_sources/usage/verilog_attributes.rst.txt b/_sources/usage/verilog_attributes.rst.txt new file mode 100644 index 0000000000..9f17c8e423 --- /dev/null +++ b/_sources/usage/verilog_attributes.rst.txt @@ -0,0 +1,35 @@ + +Verilog Attributes +================== + +This is a description of the various attributes that the Icarus Verilog tools +understand. The attributes are attached to objects using the "(\* ... \*)" +syntax, which is described by the Verilog LRM. + +Attributes that start with "ivl\_" are Icarus Verilog specific are are probably +ignored by other tools. + +Optimizations +------------- + +* ivl_do_not_elide (snapshot 20140619 or later) + + This applies to signals (i.e. reg, wire, etc.) and tells the optimizer to + not elide the signal, even if it is not referenced anywhere in the + design. This is useful if the signal is for some reason only accessed by + VPI/PLI code. + +Synthesis +--------- + +* ivl_synthesis_cell + + Applied to a module definition, this tells the synthesizer that the module + is a cell. The synthesizer does not descend into synthesis cells, as they + are assumed to be primitives in the target technology. + +* ivl_synthesis_off + + Attached to an "always" statement, this tells the synthesizer that the + statement is not to be synthesized. This may be useful, for example, to tell + the compiler that a stretch of code is test-bench code. diff --git a/_sources/usage/vhdlpp_flags.rst.txt b/_sources/usage/vhdlpp_flags.rst.txt new file mode 100644 index 0000000000..43b9c6821b --- /dev/null +++ b/_sources/usage/vhdlpp_flags.rst.txt @@ -0,0 +1,59 @@ + +vhdlpp Command Line Flags +========================= + +* -D + + Debug flags. The token can be: + + * yydebug | no-yydebug + + * entities= + +* -L + + Library path. Add the directory name to the front of the library + search path. The library search path is initially empty. + +* -V + + Display version on stdout + +* -v + + Verbose: Display version on stderr, and enable verbose messages to + stderr. + +* -w + + Work path. This is the directory where the working directory is. + + +Library Format +-------------- + +The vhdlpp program stores libraries as directory that contain +packages. The name of the directory (in lower case) is the name of the +library as used on the "import" statement. Within that library, there +are packages in files named .pkg. For example:: + + /... + sample/... + test1.pkg + test2.pkg + bar/... + test3.pkg + +Use the "+vhdl-libdir+" record in a config file to tell +Icarus Verilog that is a place to look for libraries. Then +in your VHDL code, access packages like this:: + + library sample; + library bar; + use sample.test1.all; + use bar.test3.all; + +The \*.pkg files are just VHDL code containing only the package with +the same name. When Icarus Verilog encounters the "use ..*;" +statement, it looks for the .pkg file in the library and +parses that file to get the package header declared therein. diff --git a/_sources/usage/vpi.rst.txt b/_sources/usage/vpi.rst.txt new file mode 100644 index 0000000000..24cd6f8b69 --- /dev/null +++ b/_sources/usage/vpi.rst.txt @@ -0,0 +1,246 @@ + +Using VPI +========= + +Icarus Verilog implements a portion of the PLI 2.0 API to Verilog. This allows +programmers to write C code that interfaces with Verilog simulations to +perform tasks otherwise impractical with straight Verilog. Many Verilog +designers, especially those who only use Verilog as a synthesis tool, can +safely ignore the entire matter of the PLI (and this chapter) but the designer +who wishes to interface a simulation with the outside world cannot escape VPI. + +The rest of this article assumes some knowledge of C programming, Verilog PLI, +and of the compiler on your system. In most cases, Icarus Verilog assumes the +GNU Compilation System is the compiler you are using, so tips and instructions +that follow reflect that. If you are not a C programmer, or are not planning +any VPI modules, you can skip this entire article. There are references at the +bottom for information about more general topics. + +How It Works +------------ + +The VPI modules are compiled loadable object code that the runtime loads at +the user's request. The user commands vvp to locate and load modules with the +"-m" switch. For example, to load the "sample.vpi" module:: + + % vvp -msample foo.vvp + +The vvp run-time loads the modules first, before executing any of the +simulation, or even before compiling the vvp code. Part of the loading +includes invoking initialization routines. These routines register with the +run-time all the system tasks and functions that the module implements. Once +this is done, the run time loader can match names of the called system tasks +of the design with the implementations in the VPI modules. + +(There is a special module, the system.vpi module, that is always loaded to +provide the core system tasks.) + +The simulator run time (The "vvp" program) gets a handle on a freshly loaded +module by looking for the symbol "vlog_startup_routines" in the loaded +module. This table, provided by the module author and compiled into the +module, is a null terminated table of function pointers. The simulator calls +each of the functions in the table in order. The following simple C definition +defines a sample table:: + + void (*vlog_startup_routines[])() = { + hello_register, + 0 + }; + +Note that the "vlog_startup_routines" table is an array of function pointers, +with the last pointer a 0 to mark the end. The programmer can organize the +module to include many startup functions in this table, if desired. + +The job of the startup functions that are collected in the startup table is to +declare the system tasks and functions that the module provides. A module may +implement as many tasks/functions as desired, so a module can legitimately be +called a library of system tasks and functions. + +Compiling VPI Modules +--------------------- + +To compile and link a VPI module for use with Icarus Verilog, you must compile +all the source files of a module as if you were compiling for a DLL or shared +object. With gcc under Linux, this means compiling with the "-fpic" flag. The +module is then linked together with the vpi library like so:: + + % gcc -c -fpic hello.c + % gcc -shared -o hello.vpi hello.o -lvpi + +This assumes that the "vpi_user.h header file and the libvpi.a library file +are installed on your system so that gcc may find them. This is normally the +case under Linux and UNIX systems. An easier, the preferred method that works +on all supported systems is to use the single command:: + + % iverilog-vpi hello.c + +The "iverilog-vpi" command takes as command arguments the source files for +your VPI module, compiles them with proper compiler flags, and links them into +a vpi module with any system specific libraries and linker flags that are +required. This simple command makes the "hello.vpi" module with minimum fuss. + +A Worked Example +---------------- + +Let us try a complete, working example. Place the C code that follows into the +file hello.c:: + + # include + + static int hello_compiletf(char*user_data) + { + return 0; + } + + static int hello_calltf(char*user_data) + { + vpi_printf("Hello, World!\n"); + return 0; + } + + void hello_register() + { + s_vpi_systf_data tf_data; + + tf_data.type = vpiSysTask; + tf_data.tfname = "$hello"; + tf_data.calltf = hello_calltf; + tf_data.compiletf = hello_compiletf; + tf_data.sizetf = 0; + tf_data.user_data = 0; + vpi_register_systf(&tf_data); + } + + void (*vlog_startup_routines[])() = { + hello_register, + 0 + }; + +and place the Verilog code that follows into hello.v:: + + module main; + initial $hello; + endmodule + +Next, compile and execute the code with these steps:: + + % iverilog-vpi hello.c + % iverilog -ohello.vvp hello.v + % vvp -M. -mhello hello.vvp + Hello, World! + +The compile and link in this example are conveniently combined into the +"iverilog-vpi" command. The "iverilog" command then compiles the "hello.v" +Verilog source file to the "hello.vvp" program. Next, the "vvp" command +demonstrates the use of the "-M" and "-m" flags to specify a vpi module search +directory and vpi module name. Specifically, they tell the "vvp" command where +to find the module we just compiled. + +The "vvp" command, when executed as above, loads the "hello.vpi" module that +it finds in the current working directory. When the module is loaded, the +vlog_startup_routines table is scanned, and the "hello_register" function is +executed. The "hello_register" function in turn tells "vvp" about the system +tasks that are included in this module. + +After the modules are all loaded, the "hello.vvp" design file is loaded and +its call to the "$hello" system task is matched up to the version declared by +the module. While "vvp" compiles the "hello.vvp" source, any calls to "$hello" +are referred to the "compiletf" function. This function is called at compile +time and can be used to check parameters to system tasks or function. It can +be left empty like this, or left out completely. The "compiletf" function can +help performance by collecting parameter checks in compile time, so they do +not need to be done each time the system task is run, thus potentially saving +execution time overall. + +When the run-time executes the call to the hello system task, the +"hello_calltf" function is invoked in the loaded module, and thus the output +is generated. The "calltf" function is called at run time when the Verilog +code actually executes the system task. This is where the active code of the +task belongs. + +System Function Return Types +---------------------------- + +Icarus Verilog supports system functions as well as system tasks, but there is +a complication. Notice how the module that you compile is only loaded by the +"vvp" program. This is mostly not an issue, but elaboration of expressions +needs to keep track of types, so the main compiler needs to know the return +type of functions. + +Starting with Icarus Verilog v11, the solution is quite simple. The names and +locations of the user's VPI modules can be passed to the compiler via the +"iverilog" -m and -L flags and the IVERILOG_VPI_MODULE_PATH environment +variable. The compiler will load and analyse the specified modules to +automatically determine any function return types. The compiler will also +automatically pass the names and locations of the specified modules to the +"vvp" program, so that they don't need to be specified again on the "vvp" +command line. + +For Icarus Verilog versions prior to v11, the solution requires that the +developer of a module include the table in a form that the compiler can +read. The System Function Table file carries this information. A simple +example looks like this:: + + # Example sft declarations of some common functions + $random vpiSysFuncInt + $bitstoreal vpiSysFuncReal + $realtobits vpiSysFuncSized 64 unsigned + +This demonstrates the format of the file and support types. Each line contains +a comment (starts with "#") or a type declaration for a single function. The +declaration starts with the name of the system function (including the leading +"$") and ends with the type. The supported types are: + +* vpiSysFuncInt +* vpiSysFuncReal +* vpiSysFuncSized + +Any functions that do not have an explicit type declaration in an SFT file are +implicitly taken to be "vpiSysFuncSized 32 unsigned". + +The module author provides, along with the ".vpi" file that is the module, a +".sft" that declares all the function return types. For example, if the file +is named "example.sft", pass it to the "iverilog" command line or in the +command file exactly as if it were an ordinary source file. + +Cadence PLI Modules +------------------- + +With the cadpli module, Icarus Verilog is able to load PLI1 applications that +were compiled and linked to be dynamic loaded by Verilog-XL or +NC-Verilog. This allows Icarus Verilog users to run third-party modules that +were compiled to interface with XL or NC. Obviously, this only works on the +operating system that the PLI application was compiled to run on. For example, +a Linux module can only be loaded and run under Linux. In addition, a 64-bit +version of vvp can only load 64-bit PLI1 applications, etc. + +Icarus Verilog uses an interface module, the "cadpli" module, to connect the +worlds. This module is installed with Icarus Verilog, and is invoked by the +usual -m flag to iverilog or vvp. This module in turn scans the extended +arguments, looking for -cadpli= arguments. The latter specify the share object +and bootstrap function for running the module. For example, to run the module +product.so, that has the bootstrap function "my_boot":: + + % vvp -mcadpli a.out -cadpli=./product.so:my_boot + +The "-mcadpli" argument causes vvp to load the cadpli.vpl library module. This +activates the -cadpli= argument interpreter. The -cadpli=: +argument, then, causes vvp, through the cadpli module, to load the loadable +PLI application, invoke the my_boot function to get a veriusertfs table, and +scan that table to register the system tasks and functions exported by that +object. The format of the -cadpli= extended argument is essentially the same +as the +loadpli1= argument to Verilog-XL. + +The integration from this point is seamless. The PLI application hardly knows +that it is being invoked by Icarus Verilog instead of Verilog-XL, so operates +as it would otherwise. + +Other References +---------------- + +Since the above only explains how to get PLI/VPI working with Icarus Verilog, +here are some references to material to help with the common aspects of +PLI/VPI. + +* Principles of Verilog PLI by Swapnajit Mittra. ISBN 0-7923-8477-6 +* The Verilog PLI Handbook by Stuart Sutherland. ISBN 0-7923-8489-X diff --git a/_sources/usage/vvp_debug.rst.txt b/_sources/usage/vvp_debug.rst.txt new file mode 100644 index 0000000000..ebe8c31cff --- /dev/null +++ b/_sources/usage/vvp_debug.rst.txt @@ -0,0 +1,148 @@ +VVP Interactive Mode +==================== + +The vvp command has an interactive debug mode, where you can stop the +simulation and browse the current state of the simulation. There are +a couple ways to enter the debug mode, but once in interactive debug +mode, the usage is the same. Consider the example below: + +.. code-block:: verilog + + module clock(output reg clock); + initial clock = 1'b1; + always #100 clock = !clock; + endmodule // clock + + module main; + + reg [2:0] foo; + wire clk; + + clock foo_clock(clk); + + always @(posedge clk) + foo <= foo + 1; + + initial begin + foo = 3'b000; + #250 $stop; + end + + endmodule + +In examples that follow, we will use the above sample program. + +Enter Interactive Mode +---------------------- + +The first and most common method is to put "$stop" system task +calls in the simulation at the times where you want to simulation +to break and enter interactive mode. The example above has a $stop, +so the output looks like this:: + + ../foo.vl:25: $stop called at 250 (1s) + ** VVP Stop(0) ** + ** Flushing output streams. + ** Current simulation time is 250 ticks. + > + +You can get some interactive help by using the "help" command:: + + > help + Commands can be from the following table of base commands, + or can be invocations of system tasks/functions. + + cd - Synonym for push. + cont - Resume (continue) the simulation + finish - Finish the simulation. + help - Get help. + list - List items in the current scope. + load - Load a VPI module, a la vvp -m. + ls - Shorthand for "list". + pop - Pop one scope from the scope stack. + push - Descend into the named scope. + step - Single-step the scheduler for 1 event. + time - Print the current simulation time. + trace - Control statement tracing (on/off) when the code is instrumented. + where - Show current scope, and scope hierarchy stack. + + If the command name starts with a '$' character, it + is taken to be the name of a system task, and a call is + built up and executed. For example, "$display foo" will + call the function as $display(foo). + +You can also enter interactive mode at the terminal by interrupting the +execution with a "^C" (Control-C) character. The vvp engine catches the +terminal interrupt and drops you into the interactive prompt:: + + ^C** VVP Stop(0) ** + ** Flushing output streams. + ** Current simulation time is 533928600 ticks. + > + +This could be useful if you suspect that your simulation is stuck in +an infinite loop and you want to rummage around and see what's going on. + +And finally, you can pass the "-s" command line flag to vvp to tell it +to execute "$stop" at the beginning of the simulation, before any other +events are executed. This may be useful as a way to manually set up some +details about the simulation. + +Browsing the Design +------------------- + +Now that you are in the interactive prompt, you can browse +around the design:: + + > ls + 2 items in this scope: + package : $unit + module : main + > cd main + > ls + 3 items in this scope: + reg : foo[2:0] + module : foo_clock + net : clk + > where + module main + > $display foo + 1 + > cd foo_clock + > where + module foo_clock + module main + > ls + 2 items in this scope: + port : clock -- output + reg : clock + +In the above example, the 'cd' and 'pop' commands descend into a scope +or pop back up a scope level. The 'where' command shows the scope stack, +and the 'ls' command lists the items present in the scope. With these +commands, one can browse freely throughout the design scope hierarchy. + +It is also possible to call system tasks within the debug mode. The call +to the "$display" function is an example of this. In general, any system +task can be invoked, in the current context, with the objects that are +included on the command line passed as arguments. The arguments can be +variables or nets, and various kinds of literals:: + + > ls + 2 items in this scope: + port : clock -- output + reg : clock + > $display "Hello, World! " 10 " " clock + Hello, World! 10 1 + +This is a great way to call custom system tasks as well. And system task +that vvp knows about can be invoked this way. + +Leave Interactive Mode +---------------------- + +After you are done probing around in the interactive mode, you can +resume the simulation, or termimate execution. Resume the simulation +with the "cont" command, and terminate the simulation with the +"finish" command. The latter is the same as executing the +"$finish" system task. diff --git a/_sources/usage/vvp_flags.rst.txt b/_sources/usage/vvp_flags.rst.txt new file mode 100644 index 0000000000..70bf0aa6d8 --- /dev/null +++ b/_sources/usage/vvp_flags.rst.txt @@ -0,0 +1,116 @@ +VVP Command Line Flags +====================== + +The vvp command is the simulation run-time engine. The command line for vvp +execution is first the options and flags, then the vvp input file, and finally +extended arguments. Typical usage looks like this:: + + % vvp foo.vvp + +Options/Flags +------------- + +These options/flags go before the path to the vvp-executable program. They +effect behavior of the vvp runtime engine, including preparation for +simulation. + +* -l + + This flag specifies a logfile where all MCI output goes. Specify + logfile as '-' to send log output to . $display and friends send + their output both to and . + +* -M + + Add the directory path to the (VPI) module search path. Multiple "-M" flags + are allowed, and the directories are added in the order that they are given + on the command line. + + The string "-M-" is special, in that it doesn't add a directory to the + path. It instead *removes* the compiled directory. This is generally used + only for development of the vvp engine. + +* -m + + Name a VPI module that should be loaded. The vvp engine looks for the named + module in the module search path, which includes the compiled in default + directory and directories given by "-M" flags. + + NOTE: Starting with v11.0, the VPI modules to be loaded can be specified + when you compile your design. This allows the compiler to automatically + determine the return types of user-defined system functions. If specified at + compile-time, there is no need to specify them again here. + +* -s + + $stop right away, in the beginning of the simulation. This kicks the + vvp program into interactive debug mode. + +* -v + + Show verbose progress while setting up or cleaning up the runtime + engine. This also displays some performance information. + +Extended Arguments +------------------ + +The extended arguments are available to the simulation runtime, especially +system tasks, system functions and any VPI/PLI code. Extended arguments that +start with a "+" character are left for use by the user via the $plus$flag and +$plus$value functions. + +VCD/FST/LXT Arguments +^^^^^^^^^^^^^^^^^^^^^ + +If not otherwise specified, the vvp engine will by default use VCD formats to +support the $dumpvars system task. The flags described here can alter that +behavior. + +* -none/-vcd-none/-vcd-off/-fst-none + + Disable trace output. The trace output will be stubbed so that no trace file + is created and the cost of dumping is avoided. All off these options are + synonyms for turning of dumping. + +* -fst + + Generate FST format outputs instead of VCD format waveform dumps. This is + the preferred output format if using GTKWave for viewing waveforms. + +* -lxt/-lxt2 + + Generate LXT or LXT2format instead of VCD format waveform dumps. The LXT2 + format is more advanced. + +* -dumpfile= + + Set the default dumpfile. If unspecified, the default is "dump". This + command line flag allows you do change it. If no suffix is specified, + then the suffix will be chosen based on the dump type. In any case, the + $dumpfile system task overrides this flag. + +SDF Support +^^^^^^^^^^^ + +The Icarus Verilog support for SDF back-annotation can take some extended +arguments to control aspects of SDF support. + +* -sdf-warn + + Print warnings during load of/annotation from an SDF file. + +* -sdf-info + + Print interesting information about an SDF file while parsing it. + +* -sdf-verbose + + Print warnings and info messages. + +Environment Variables +--------------------- + +The vvp program pays attention to certain environment variables. + +* IVERILOG_DUMPER + diff --git a/_sources/usage/vvp_library.rst.txt b/_sources/usage/vvp_library.rst.txt new file mode 100644 index 0000000000..62b892bd77 --- /dev/null +++ b/_sources/usage/vvp_library.rst.txt @@ -0,0 +1,29 @@ +VVP as a library +================ + +If configured with :: + + --enable-libvvp + +the vvp program will be built as a small stub that +depends on a shared library, libvvp.so. +The library may also be used to include a vvp simulation +in a larger program. Typically, the simulation communicates +with its host program using VPI, but since +almost all the functions of vvp are included in the library +it may be possible to use text output and interactive mode. + +The accessible functions of the library are defined and documented +in the header file, vvp/libvvp.h. Although vvp is a C++ program, the +header file presents a C interface. + +Note that the vvp software was not designed to be used this way +and the library is a straightforward recompilation of the program code. +That imposes some restrictions, mostly arising from the use +of static variables: only a single run of a single simulation instance +can be expected to work without special actions. +To mitigate these restrictions, the library may by loaded dynamically +and unloaded at the end of each simulation run. +Parallel simulation should be possible by making multiple copies +of the library with different names. + diff --git a/_static/alabaster.css b/_static/alabaster.css new file mode 100644 index 0000000000..0eddaeb07d --- /dev/null +++ b/_static/alabaster.css @@ -0,0 +1,701 @@ +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: Georgia, serif; + font-size: 17px; + background-color: #fff; + color: #000; + margin: 0; + padding: 0; +} + + +div.document { + width: 940px; + margin: 30px auto 0 auto; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 220px; +} + +div.sphinxsidebar { + width: 220px; + font-size: 14px; + line-height: 1.5; +} + +hr { + border: 1px solid #B1B4B6; +} + +div.body { + background-color: #fff; + color: #3E4349; + padding: 0 30px 0 30px; +} + +div.body > .section { + text-align: left; +} + +div.footer { + width: 940px; + margin: 20px auto 30px auto; + font-size: 14px; + color: #888; + text-align: right; +} + +div.footer a { + color: #888; +} + +p.caption { + font-family: inherit; + font-size: inherit; +} + + +div.relations { + display: none; +} + + +div.sphinxsidebar a { + color: #444; + text-decoration: none; + border-bottom: 1px dotted #999; +} + +div.sphinxsidebar a:hover { + border-bottom: 1px solid #999; +} + +div.sphinxsidebarwrapper { + padding: 18px 10px; +} + +div.sphinxsidebarwrapper p.logo { + padding: 0; + margin: -10px 0 0 0px; + text-align: center; +} + +div.sphinxsidebarwrapper h1.logo { + margin-top: -10px; + text-align: center; + margin-bottom: 5px; + text-align: left; +} + +div.sphinxsidebarwrapper h1.logo-name { + margin-top: 0px; +} + +div.sphinxsidebarwrapper p.blurb { + margin-top: 0; + font-style: normal; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4 { + font-family: Georgia, serif; + color: #444; + font-size: 24px; + font-weight: normal; + margin: 0 0 5px 0; + padding: 0; +} + +div.sphinxsidebar h4 { + font-size: 20px; +} + +div.sphinxsidebar h3 a { + color: #444; +} + +div.sphinxsidebar p.logo a, +div.sphinxsidebar h3 a, +div.sphinxsidebar p.logo a:hover, +div.sphinxsidebar h3 a:hover { + border: none; +} + +div.sphinxsidebar p { + color: #555; + margin: 10px 0; +} + +div.sphinxsidebar ul { + margin: 10px 0; + padding: 0; + color: #000; +} + +div.sphinxsidebar ul li.toctree-l1 > a { + font-size: 120%; +} + +div.sphinxsidebar ul li.toctree-l2 > a { + font-size: 110%; +} + +div.sphinxsidebar input { + border: 1px solid #CCC; + font-family: Georgia, serif; + font-size: 1em; +} + +div.sphinxsidebar hr { + border: none; + height: 1px; + color: #AAA; + background: #AAA; + + text-align: left; + margin-left: 0; + width: 50%; +} + +div.sphinxsidebar .badge { + border-bottom: none; +} + +div.sphinxsidebar .badge:hover { + border-bottom: none; +} + +/* To address an issue with donation coming after search */ +div.sphinxsidebar h3.donation { + margin-top: 10px; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #004B6B; + text-decoration: underline; +} + +a:hover { + color: #6D4100; + text-decoration: underline; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: Georgia, serif; + font-weight: normal; + margin: 30px 0px 10px 0px; + padding: 0; +} + +div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } +div.body h2 { font-size: 180%; } +div.body h3 { font-size: 150%; } +div.body h4 { font-size: 130%; } +div.body h5 { font-size: 100%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #DDD; + padding: 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + color: #444; + background: #EAEAEA; +} + +div.body p, div.body dd, div.body li { + line-height: 1.4em; +} + +div.admonition { + margin: 20px 0px; + padding: 10px 30px; + background-color: #EEE; + border: 1px solid #CCC; +} + +div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fafafa; +} + +div.admonition p.admonition-title { + font-family: Georgia, serif; + font-weight: normal; + font-size: 24px; + margin: 0 0 10px 0; + padding: 0; + line-height: 1; +} + +div.admonition p.last { + margin-bottom: 0; +} + +div.highlight { + background-color: #fff; +} + +dt:target, .highlight { + background: #FAF3E8; +} + +div.warning { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.danger { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.error { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.caution { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.attention { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.important { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.note { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.tip { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.hint { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.seealso { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.topic { + background-color: #EEE; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre, tt, code { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; + font-size: 0.9em; +} + +.hll { + background-color: #FFC; + margin: 0 -12px; + padding: 0 12px; + display: block; +} + +img.screenshot { +} + +tt.descname, tt.descclassname, code.descname, code.descclassname { + font-size: 0.95em; +} + +tt.descname, code.descname { + padding-right: 0.08em; +} + +img.screenshot { + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils { + border: 1px solid #888; + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils td, table.docutils th { + border: 1px solid #888; + padding: 0.25em 0.7em; +} + +table.field-list, table.footnote { + border: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +table.footnote { + margin: 15px 0; + width: 100%; + border: 1px solid #EEE; + background: #FDFDFD; + font-size: 0.9em; +} + +table.footnote + table.footnote { + margin-top: -15px; + border-top: none; +} + +table.field-list th { + padding: 0 0.8em 0 0; +} + +table.field-list td { + padding: 0; +} + +table.field-list p { + margin-bottom: 0.8em; +} + +/* Cloned from + * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 + */ +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +table.footnote td.label { + width: .1px; + padding: 0.3em 0 0.3em 0.5em; +} + +table.footnote td { + padding: 0.3em 0.5em; +} + +dl { + margin: 0; + padding: 0; +} + +dl dd { + margin-left: 30px; +} + +blockquote { + margin: 0 0 0 30px; + padding: 0; +} + +ul, ol { + /* Matches the 30px from the narrow-screen "li > ul" selector below */ + margin: 10px 0 10px 30px; + padding: 0; +} + +pre { + background: #EEE; + padding: 7px 30px; + margin: 15px 0px; + line-height: 1.3em; +} + +div.viewcode-block:target { + background: #ffd; +} + +dl pre, blockquote pre, li pre { + margin-left: 0; + padding-left: 30px; +} + +tt, code { + background-color: #ecf0f3; + color: #222; + /* padding: 1px 2px; */ +} + +tt.xref, code.xref, a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fff; +} + +a.reference { + text-decoration: none; + border-bottom: 1px dotted #004B6B; +} + +/* Don't put an underline on images */ +a.image-reference, a.image-reference:hover { + border-bottom: none; +} + +a.reference:hover { + border-bottom: 1px solid #6D4100; +} + +a.footnote-reference { + text-decoration: none; + font-size: 0.7em; + vertical-align: top; + border-bottom: 1px dotted #004B6B; +} + +a.footnote-reference:hover { + border-bottom: 1px solid #6D4100; +} + +a:hover tt, a:hover code { + background: #EEE; +} + + +@media screen and (max-width: 870px) { + + div.sphinxsidebar { + display: none; + } + + div.document { + width: 100%; + + } + + div.documentwrapper { + margin-left: 0; + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + } + + div.bodywrapper { + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + margin-left: 0; + } + + ul { + margin-left: 0; + } + + li > ul { + /* Matches the 30px from the "ul, ol" selector above */ + margin-left: 30px; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .bodywrapper { + margin: 0; + } + + .footer { + width: auto; + } + + .github { + display: none; + } + + + +} + + + +@media screen and (max-width: 875px) { + + body { + margin: 0; + padding: 20px 30px; + } + + div.documentwrapper { + float: none; + background: #fff; + } + + div.sphinxsidebar { + display: block; + float: none; + width: 102.5%; + margin: 50px -30px -20px -30px; + padding: 10px 20px; + background: #333; + color: #FFF; + } + + div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, + div.sphinxsidebar h3 a { + color: #fff; + } + + div.sphinxsidebar a { + color: #AAA; + } + + div.sphinxsidebar p.logo { + display: none; + } + + div.document { + width: 100%; + margin: 0; + } + + div.footer { + display: none; + } + + div.bodywrapper { + margin: 0; + } + + div.body { + min-height: 0; + padding: 0; + } + + .rtd_doc_footer { + display: none; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .footer { + width: auto; + } + + .github { + display: none; + } +} + + +/* misc. */ + +.revsys-inline { + display: none!important; +} + +/* Make nested-list/multi-paragraph items look better in Releases changelog + * pages. Without this, docutils' magical list fuckery causes inconsistent + * formatting between different release sub-lists. + */ +div#changelog > div.section > ul > li > p:only-child { + margin-bottom: 0; +} + +/* Hide fugly table cell borders in ..bibliography:: directive output */ +table.docutils.citation, table.docutils.citation td, table.docutils.citation th { + border: none; + /* Below needed in some edge cases; if not applied, bottom shadows appear */ + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + + +/* relbar */ + +.related { + line-height: 30px; + width: 100%; + font-size: 0.9rem; +} + +.related.top { + border-bottom: 1px solid #EEE; + margin-bottom: 20px; +} + +.related.bottom { + border-top: 1px solid #EEE; +} + +.related ul { + padding: 0; + margin: 0; + list-style: none; +} + +.related li { + display: inline; +} + +nav#rellinks { + float: right; +} + +nav#rellinks li+li:before { + content: "|"; +} + +nav#breadcrumbs li+li:before { + content: "\00BB"; +} + +/* Hide certain items when printing */ +@media print { + div.related { + display: none; + } +} \ No newline at end of file diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 0000000000..603f6a8798 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,905 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 450px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +dl.footnote > dt, +dl.citation > dt { + float: left; + margin-right: 0.5em; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dt:after { + content: ":"; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/custom.css b/_static/custom.css new file mode 100644 index 0000000000..2a924f1d6a --- /dev/null +++ b/_static/custom.css @@ -0,0 +1 @@ +/* This file intentionally left blank. */ diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 0000000000..8cbf1b161a --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,323 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { + this.initOnKeyListeners(); + } + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keydown(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box, textarea, dropdown or button + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' + && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey + && !event.shiftKey) { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + break; + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + break; + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 0000000000..2fa8c97fe4 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,12 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '', + LANGUAGE: 'None', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false +}; \ No newline at end of file diff --git a/_static/favicon.ico b/_static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..342e9f39e25f3857dc5eb25ac54d646b39ce512e GIT binary patch literal 1150 zcmZvbZA?>F7{@O!Q?r-ML}#KO7C$TwRG4VWM%idLUgjWd719V&!3oX^4yib+aq3(I zoO{WP5%GhW(I_*~MW!+pET94d0<#LELTP)U!o7vt)?O)?sh+VE!2nT^3IYa zbTxdEFodjBH@0o~2g=pwks&{f&yso(zuZD{@F-ABV&hs4anbGevC*k{l<)6*^m=+q z&+%pNbo%9z32ZO)AaSJ<2X{E3NGnBF+AtDVu#iivNKdk%Y@-{=iQWE!T>U1pjtHV~ zxwP%_%BBC3SUV2wnxY>BTU3{VwpcZZ>{JIbWdbr}gIJp`K%-_6x3p=v?hkH}&lh+_ zt7*9{jWc4$CJ%nu3w)lU4YHb|dTh>}LUEpmZ`8xsSz!<$g6^6LtZ5V~1rJ5CfU3O?#Jt;RJM_IFisT3z zv)WFMT5afV8^oEKTS1ntfoh?`v^F8v!yMMnXxJ%a5+1LTyxIB2ecetvPE-kJKtos`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHDfiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( literal 0 HcmV?d00001 diff --git a/_static/forkme_right_darkblue_121621.png b/_static/forkme_right_darkblue_121621.png new file mode 100644 index 0000000000000000000000000000000000000000..91c7bd8edfa0720adbefd523d9273d945d88e140 GIT binary patch literal 4787 zcmXX~2{csgA7<=hNf@#=WSyB(mTXzZntd?CSYonkLdsG?))-W_8Cz=jD0{}%$P#5N zGbDu~OCO1>W#9cr-~XO-?|aUDf7|l*-`Rn8fBOYdbh@ z3o3c30oYv$fXXwnfZ05wv*Om1b=3!Q-ml9Rm41^XS0EL@;+{Tpj;@YgijS-nZNjG1 z9YJT+-0@BmL*I1as+;0j1%dkoX*sru9*s;KIeL*mfwqgqrH z<@Rp5Z;)4_ao1e$i@oD6xnh;?IR$#G-X0V_TZ-6K{H?D?JSBh^l`iXv?sb`ata4>- zW%)q!Wfz?4mCGiZ{o3(_LpdGECXVhU05t|}WDO;xK^6dI89c>Qz%G&bD|qB3#!Tii^RigXZ+{^S~9>wmRuET&BE*IX#<^}f8O9z_VkNeV4f9{+U z!qQ+ZbuWiw`8Hqi((aa7*;h!Xh1)a$CZ9%NrFpAgmW`rr_@Dg_Y1!9rsDIOD^8TMY zp0!O0Xx6JCUJY;Lof+AF`~1w2g0-CD8bEM%PAho$eYlu^og{ePNs`T$;&PGQQg@Km zJcjuxxV;mISNlYLqm%Swp)Aeo?XM=)L$Y-Lv31hshV6toEOYrTZ*L0no)M6RCh8j= z`p8L()rg{WwfsJgVy}6V7ngh5Av0{G$g$zZ&Ey(y!1Yz;JHGyklxNn(vT(I`zq~wquAoYbC%nsy5p+CtrbhOKnxxu~el4${4>6GF zp z2N{m1v$sENmwhZuW=wIE)c-+&z7}oX7JsfxWVVy_QIWV3er;yzcvmq!W^+~+Jv(Yv z$X9?juu58Y28x&Oq#AjHoh1#|LJl+Jh=e)4i3b~F52N=cR*!uI|_pK3)Qu4I93zIj+ zG(vSKmGrt;QZDgS^!5RBRvETMny97n2~PnaAQGYt%c_5 zIq}5gB%8_8QUgz$ji0DOOVwxb_!a{bD<(n$gv<;<>v`HIt+jblK1RgNA}HQ4!alEw z21qK+9^Mer&B!!_?KRUdq$$^2aB0hZ5Vh_+W#swpr|%`_gg6RbQHh|qCli~TG!}rd zzk4`huvdAr__M>PopzrR$WpyMEq%ybysvg>>gdQCp8cTp-hSH_MnSU=csk&fOS4JW z+D~m3BuSVCOqZW5Al7EYwvV;=zlx^T4N+j&KZjr1{uIa}DYj@;xvaGhAGFl!!7WXc9bbTBFv5G5uKSOMwP7S1!4Lb)|$QTi`cQx5=X#n}GvoyzYS zY)b6jGMDehqXx&O z&La9LI)wP1=&piPqbFWgapvCuMwdmOPezaPUO87^r=J`9{W5H zqp5?Du+MRfc!6yv%%4T7`G%hb-1sLWEb&G)K1^`oRz5t53y`9E2H$cj@<-12_K^66>AgfJ$x!gNu-Ed50KR4rN^)XFg7q1_wkK446eg^>Vii?1eWG=@S|`S>yi zq)FEe$FS*-wA1{bMSE>Mp^U>o!PayZ*cq7W>e{lI=ShvRUK2QHd>Gi5CFS4W0}pnw zOje9Aj#6I-NJ@jq-QCdTuXm&~;YF5kv2te2Ao#T!i{G8mU?nC_v;ZJ^6s+f$xzQhZ zKa8y=91@3%wt(|Jr3(bQrc&!tk>{_5yWgO~rHyBZ@{cxLoB*i|DJ2H@`BK|?giMBL zrB={9=$@8xJytn2IEy6J@lJrbj<41aXvdofx$Gev=6(lKZ^Mvc>l>plJGLO%JK^?2(~rP_ZmZSe7~l%LTaEx zmM*~nf6Lx?90zT8dUlu)D4zunhjwgqJc)=6@oIZp#F==o3vG%?lH}2SgqIuylX7?S9d529e2KXDdUCW7;{vB|u)cw_0 z(XeT7woVg`L2w=3tmM&QizWj)K2`EgT^RAUCHK?2AWRRWtX7H6Excli3KUJOt2KK< z@yT!X_5;RlblkYT!35wz6*(4$$QkFrL}$_G%_VclT0MDOxfa*IcrTFqdtPH#Ea;3u zz5tW^kvv3}>~=oHhT~Q4O6Ypzii(|eB-^cESoMRF6A*vSGcxAJBCGq^VP*x*g@asUKkZ@n44<+wh?i|EO>}_tk6sinxz$#mRsfj3AM#6 zaPdzoCLi5Ia*?mPwV4^{AoU;r=(x~)5<)?_=4CT>i{}yJN#1?`oVN|HsfA+T)lu)W z=IweVci#MsPyl02Sx`9DP2t-_WW;P#csdk zt>L{oSgpQ0TCsJ|Qm_{w$w|+uz}|MP+tNlGEqS(-@1*u9s8~Yvt^R8s*cek82c7Uggdmaqo32EL2lp|yw>0gFpjvEN|y|p1g|_4w-sM{2onj{$4Hj) z6|zcp3B+^TMl=^G*-Mp*(dEhFSef%x7)POSj!&AHfFKNSDwe5`&~buQPHg7}8b`cM z7Yfp0%5uFa)zsQ+03c&Yiw)VC7v6NCqVXbvaGbaL2SLA7g{vn4XRO9`JU~7P2M>^Y zKMbg-i*0jtU=KZRbe5Ut!^?}xhPzi2? zY!?}6SuL$wM!*r@-?zRize4>UZEMtoI-eW4N4`oM>oa#76bgb^0Pt$7BL(U|yilE1 zU`hVS<3wFS1X@^OXY!q#^Es+~$;Ekh7G(?kd`{v;e)z0##k|!OTN_|D?X0<+ffE1q zm<%Rv-MNf}>VKI;Ff1I!Ys<+OSxh$-5n6$PN?P4L!v7+ZR~E?E`zc{|z0!#A14i9&iHZ z$W{$7kMpT;EEAAWk1#9wxZxm^ZLd|j5+BjrIIt7SvW@0shPdUERyqq;K^df>_Rj_l zX53T99ZwYEQtwu(-;jA|Mn)ECRJBDo<|y<4VyVi65V?R>j)}4uIsS%lkHH$IT#*ph z>s9+AIT6kJXX!&J_?-#RB_PcX^G_zQ7r$xssKuLI-wAz>`24z}p9v6YS>q~OBPfg1 zfvV6+kH-WxaNZg+7<9AQEB3Jgs4ggo#PuzCYDXOGnKd!C|5Nvo>wq3~{BlEaJE!~>38Gq=%*LFD(Y}M-!b_wik9|fauTyv~J!Kf9V;P!4P*u`o4Tp zHUC>y(5{Z2o(WuUmcM36^HS;fiO)A1UPSu9$$lJFG0J^3#QpVKk{%1J&Z^Qbop_ra z?OkvN8O2!9U^O1WjJJ-s*+sWZKG-5HX$GyIMn?T{E&RW0!xx-eEL9HEUr7%ohsmWU z-erL`TUD-tVw1&;;eGU!S7uuEo2|GY&!dN3<)WDAtJeq)J}XocT=4aZ9s}~n-!s!+ z=#u(0NsnWrlg0klBz%Plv)BpbL=Fj$i2j<9r*1842H8Ad28BFCnZ7Cx z17N?Ll=tRcxGc!_T&sx5F5#LSAzM_>2>afwSkCqZxm>>Lh-77v-!5XFo&~A)vAz5_ zWvY_j&H)|iC(n`$wZZuD3hBCx;1WCPXsDf~u6gp@=PsL2+ou!k(-BTNVyJQU&!#11 zpB5@cl+fC7SQtxYZ1I7n5U9I9Cd4|NNR}{-^e1k@DIqZ-4nY&I+v^jF)0*vhl#=#( zRYXvGUP^^{DcPz elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 + // Plus for old WebKit, typeof returns "function" for HTML collections + // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) + return typeof obj === "function" && typeof obj.nodeType !== "number" && + typeof obj.item !== "function"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.6.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), + function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); + } ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.6 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2021-02-16 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem && elem.namespaceURI, + docElem = elem && ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +} +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the primary Deferred + primary = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + primary.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( primary.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return primary.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); + } + + return primary.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + + // Support: Chrome 86+ + // In Chrome, if an element having a focusout handler is blurred by + // clicking outside of it, it invokes the handler synchronously. If + // that handler calls `.remove()` on the element, the data is cleared, + // leaving `result` undefined. We need to guard against this. + return result && result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + which: true +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + // Suppress native focus or blur as it's already being fired + // in leverageNative. + _default: function() { + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + // + // Support: Firefox 70+ + // Only Firefox includes border widths + // in computed dimensions. (gh-4529) + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; + tr.style.cssText = "border:1px solid"; + + // Support: Chrome 86+ + // Height set through cssText does not get applied. + // Computed height then comes back as 0. + tr.style.height = "1px"; + trChild.style.height = "9px"; + + // Support: Android 8 Chrome 86+ + // In our bodyBackground.html iframe, + // display for all div elements is set to "inline", + // which causes a problem only in Android 8 Chrome 86. + // Ensuring the div is display: block + // gets around this issue. + trChild.style.display = "block"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + + parseInt( trStyle.borderTopWidth, 10 ) + + parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml, parserErrorElem; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) {} + + parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; + if ( !xml || parserErrorElem ) { + jQuery.error( "Invalid XML: " + ( + parserErrorElem ? + jQuery.map( parserErrorElem.childNodes, function( el ) { + return el.textContent; + } ).join( "\n" ) : + data + ) ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ).filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ).map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + +originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script but not if jsonp + if ( !isSuccess && + jQuery.inArray( "script", s.dataTypes ) > -1 && + jQuery.inArray( "json", s.dataTypes ) < 0 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Getting Started as a Contributer

+

Icarus Verilog development is centered around the github repository at +github.com/steveicarus/iverilog. +Contributing to Icarus Verilog requires a basic knowledge of git and github, +so see the github documentation for more information. The sections below will +step you through the basics of getting the source code from github, making a +branch, and submitting a pull request for review.

+
+

Getting Icarus Verilog

+

To start, you will need to clone the code. It is preferred that you use the +“ssh” method, and the ssh based clone with the command:

+
% git clone git@github.com:steveicarus/iverilog.git
+
+
+

This assumes that you have a github account (accounts are free) and you have +set up your ssh authentication keys. See the +Authentication Guides here.

+

The “git clone” command will get you all the source:

+
% git clone git@github.com:steveicarus/iverilog.git
+Cloning into 'iverilog'...
+remote: Enumerating objects: 66234, done.
+remote: Counting objects: 100% (6472/6472), done.
+remote: Compressing objects: 100% (4123/4123), done.
+remote: Total 66234 (delta 2412), reused 6039 (delta 2190), pack-reused 59762
+Receiving objects: 100% (66234/66234), 27.98 MiB | 2.53 MiB/s, done.
+Resolving deltas: 100% (50234/50234), done.
+% cd iverilog/
+
+
+

Normally, this is enough as you are now pointing at the most current +development code, and you have implicitly created a branch “master” that +tracks the development head. However, If you want to actually be working on a +specific version, say for example version 11, the v11-branch, you checkout +that branch with the command:

+
% git checkout --track -b v11-branch origin/v11-branch
+
+
+

This creates a local branch that tracks the v11-branch in the repository, and +switches you over to your new v11-branch. The tracking is important as it +causes pulls from the repository to re-merge your local branch with the remote +v11-branch. You always work on a local branch, then merge only when you +push/pull from the remote repository.

+

Now that you’ve cloned the repository and optionally selected the branch you +want to work on, your local source tree may later be synced up with the +development source by using the git command:

+
% git pull
+Already up to date.
+
+
+

Finally, configuration files are built by the extra step:

+
% sh autoconf.sh
+Autoconf in root...
+Precompiling lexor_keyword.gperf
+Precompiling vhdlpp/lexor_keyword.gperf
+
+
+

You will need autoconf and gperf installed in order for the script to work. +If you get errors such as:

+
% sh autoconf.sh
+Autoconf in root...
+autoconf.sh: 10: autoconf: not found
+Precompiling lexor_keyword.gperf
+autoconf.sh: 13: gperf: not found.
+
+
+

You will need to install download and install the autoconf and gperf tools.

+

Now you are ready to configure and compile the source.

+
+
+

Icarus Specific Configuration Options

+

Icarus takes many of the standard configuration options and those will not be +described here. The following are specific to Icarus Verilog:

+
--enable-suffix[=suffix]
+
+
+

This option allows the user to build Icarus with a default suffix or when +provided a user defined suffix. All programs or directories are tagged with +this suffix. e.g.(iverilog-0.8, vvp-0.8, etc.). The output of iverilog will +reference the correct run time files and directories. The run time will check +that it is running a file with a compatible version e.g.(you can not run a +V0.9 file with the V0.8 run time).

+

A debug options is:

+
--with-valgrind
+
+
+

This option adds extra memory cleanup code and pool management code to allow +better memory leak checking when valgrind is available. This option is not +need when checking for basic errors with valgrind.

+
+
+

Compiling on Linux

+

(Note: You will need to install bison, flex, g++ and gcc) This is probably the +easiest step. Given that you have the source tree from the above instructions, +the compile and install is generally as simple as:

+
% ./configure
+configure: loading site script /usr/share/site/x86_64-unknown-linux-gnu
+checking build system type... x86_64-unknown-linux-gnu
+checking host system type... x86_64-unknown-linux-gnu
+checking for gcc... gcc
+checking whether the C compiler works... yes
+checking for C compiler default output file name... a.out
+checking for suffix of executables...
+[...and so on...]
+
+% make
+mkdir dep
+Using git-describe for VERSION_TAG
+g++ -DHAVE_CONFIG_H -I. -Ilibmisc  -Wall -Wextra -Wshadow   -g -O2 -MD -c main.cc -o main.o
+mv main.d dep/main.d
+g++ -DHAVE_CONFIG_H -I. -Ilibmisc  -Wall -Wextra -Wshadow   -g -O2 -MD -c async.cc -o async.o
+mv async.d dep/async.d
+g++ -DHAVE_CONFIG_H -I. -Ilibmisc  -Wall -Wextra -Wshadow   -g -O2 -MD -c design_dump.cc -o design_dump.o
+mv design_dump.d dep/design_dump.d
+g++ -DHAVE_CONFIG_H -I. -Ilibmisc  -Wall -Wextra -Wshadow   -g -O2 -MD -c discipline.cc -o discipline.o
+[...and so on...]
+
+
+

The end result is a complete build of Icarus Verilog. You can install your +compiled version with a command like this:

+
% sudo make install
+
+
+
+
+

Regression Tests

+

Icarus Verilog comes with a fairly extensive regression test suite. As of +2022, that test suite is included with the source in the “ivtest” +directory. Contained in that directory are a couple driver scripts that run +all the regression tests on the installed version of Icarus Verilog. So for +example:

+
% cd ivtest
+% ./vvp_reg.pl --strict
+
+
+

will run all the regression tests for the simulation engine. (This is what +most people will want to do.) You should rerun this test before submitting +patches to the developers. Also, if you are adding a new feature, you should +add test programs to the regression test suite to validate your new feature +(or bug fix.)

+

Note that pull requests will be required to pass these regression tests before +being merged.

+
+
+

Forks, Branches and Pull Requests

+

Currently, the preferred way to submit patches to Icarus Verilog is via pull +requests. +Pull requests +can be created from the main repository if you have write access (very few +people have write access) or more commonly from a fork, so the first step is +to create a fork that you can work with. It is easy enough to create a fork, +just go to the +github.com/steveicarus/iverilog +page and use the “fork” button in the upper right corner. This will create +a new repository that you can clone instead of the steveicarus/iverilog +repository. You then use your local repository to create feature branches, +then submit them for inclusion in the main repository as pull +requests. Remember to synchronize your fork +periodically with the main repository. This will make sure your work is based +on the latest upstream and avoid merge conflicts.

+

Create your patch by first creating a branch that contains your commits:

+
% git checkout -b my-github-id/branch-name
+
+
+

We are encouraging using this scheme for naming your branches that are +destined for pull requests. Use your github id in the branch name. So for +example:

+
% git checkout -b steveicarus/foo-feature
+
+
+

Do your work in this branch, then when you are ready to create a pull request, +first push the branch up to github:

+
% git push -u origin my-github-id/branch-name
+
+
+

Then go to github.com to create your pull request. Create your pull request +against the “master” branch of the upstream repository, +or the version branch that you are working on. Your pull reuqest will be run +through continuous integration, and reviewed by one of the main +authors. Feedback may be offered to your PR, and once accepted, an approved +individual will merge it for you. Then you are done.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/glossary.html b/developer/glossary.html new file mode 100644 index 0000000000..ef3ce3dd88 --- /dev/null +++ b/developer/glossary.html @@ -0,0 +1,152 @@ + + + + + + + + + Glossary — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Glossary

+

Throughout Icarus Verilog descriptions and source code, I use a +variety of terms and acronyms that might be specific to Icarus +Verilog, have an Icarus Verilog specific meaning, or just aren’t +widely known. So here I define these terms.

+
+
LRM - Language Reference Manual

This is a generic acronym, but in the Verilog world we sometimes +mean the language reference manual, the IEEE1364 standard.

+
+
PLI - Programming Language Interface

This is a C API into Verilog simulators that is defined by the +IEEE1364. There are two major interfaces, sometimes called PLI 1 +and PLI 2. PLI 2 is also often called VPI.

+
+
UDP - User Defined Primitive

These are objects that Verilog programmers define with the +“primitive” keyword. They are truth-table based devices. The +syntax for defining them is described in the LRM.

+
+
VPI - Verilog Procedural Interface

This is the C API that is defined by the Verilog standard, and +that Icarus Verilog partially implements. See also PLI.

+
+
VVM - Verilog Virtual Machine

This is the Icarus Verilog runtime that works with the code +generator that generates C++.

+
+
VVP - Verilog Virtual Processor

This is the Icarus Verilog runtime that reads in custom code in a +form that I call “VVP Assembly”.

+
+
LPM - Library of Parameterized Modules

LPM (Library of Parameterized Modules) is EIS-IS standard 103-A. It is +a standard library of abstract devices that are designed to be close +enough to the target hardware to be easily translated, yet abstract +enough to support a variety of target technologies without excessive +constraints. Icarus Verilog uses LPM internally to represent idealized +hardware, especially when doing target neutral synthesis.

+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/cadpli/cadpli.html b/developer/guide/cadpli/cadpli.html new file mode 100644 index 0000000000..3caf2b67d6 --- /dev/null +++ b/developer/guide/cadpli/cadpli.html @@ -0,0 +1,151 @@ + + + + + + + + + Cadence PLI1 Modules — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Cadence PLI1 Modules

+

With the cadpli module, Icarus Verilog is able to load PLI1 +applications that were compiled and linked to be dynamic loaded by +Verilog-XL or NC-Verilog. This allows Icarus Verilog users to run +third-party modules that were compiled to interface with XL or +NC. Obviously, this only works on the operating system that the PLI +application was compiled to run on. For example, a Linux module can +only be loaded and run under Linux.

+

Icarus Verilog uses an interface module, the “cadpli” module, to +connect the worlds. This module is installed with Icarus Verilog, and +is invoked by the usual -m flag to iverilog or vvp. This module in +turn scans the extended arguments, looking for +cadpli= arguments. The +latter specify the share object and bootstrap function for running the +module. For example, to run the module product.so, that has the +bootstrap function “my_boot”:

+
vvp -mcadpli a.out -cadpli=./product.so:my_boot
+
+
+

The “-mcadpli” argument causes vvp to load the cadpli.vpl library +module. This activates the -cadpli= argument interpreter. The +-cadpli=<module>:<boot_func> argument, then, causes vvp, through the +cadpli module, to load the loadable PLI application, invoke the +my_boot function to get a veriusertfs table, and scan that table to +register the system tasks and functions exported by that object. The +format of the -cadpli= extended argument is essentially the same as +the +loadpli1= argument to Verilog-XL.

+

The integration from this point is seamless. The PLI application +hardly knows that it is being invoked by Icarus Verilog instead of +Verilog-XL, so operates as it would otherwise.

+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/index.html b/developer/guide/index.html new file mode 100644 index 0000000000..9142bc25cc --- /dev/null +++ b/developer/guide/index.html @@ -0,0 +1,301 @@ + + + + + + + + + Developer Guide — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Developer Guide

+

The developer guide is intended to give you a gross structure of the +Icarus Verilog compiler source. This will help orient you to the +source code itself, so that you can find the global parts where you +can look for even better detail.

+

The documentation for getting, building and installing Icarus Verilog +is kept and maintained at Getting Started as a Contributer

+

See the Installation Guide for getting the current source from the git +repository (and how to use the git repository) and see the Developer Guide +for instructions on participating in the Icarus Verilog development process. +That information will not be repeated here.

+

Scroll down to a listing with further readings.

+
+

Compiler Components

+
    +
  • The compiler driver (driver/)

  • +
+

This is the binary that is installed as “iverilog”. This program takes +the command line arguments and assembles invocations of all the other +subcommands to perform the steps of compilation.

+
    +
  • The preprocessor (ivlpp/)

  • +
+

This implements the Verilog pre-processor. In Icarus Verilog, the +compiler directives `define, `include, `ifdef and etc. are implemented +in an external program. The ivlpp/ directory contains the source for +this program.

+
    +
  • The core compiler (root directory)

  • +
+

The “ivl” program is the core that does all the Verilog compiler +processing that is not handled elsewhere. This is the main core of the +Icarus Verilog compiler, not the runtime. See below for more details +on the core itself.

+
    +
  • The loadable code generators (tgt-*/)

  • +
+

This core compiler, after it is finished with parsing and semantic +analysis, uses loadable code generators to emit code for supported +targets. The tgt-*/ directories contains the source for the target +code generators that are bundled with Icarus Verilog. The tgt-vvp/ +directory in particular contains the code generator for the vvp +runtime.

+
+
+

Runtime Components

+
    +
  • The vvp runtime (vvp/)

  • +
+

This program implements the runtime environment for Icarus +Verilog. It implements the “vvp” command described in the user +documentation. See the vvp/ subdirectory for further developer +documentation.

+
    +
  • The system tasks implementations (vpi/)

  • +
+

The standard Verilog system tasks are implemented using VPI (PLI-2) +and the source is in this subdirectory.

+
    +
  • The PLI-1 compatibility library (libveriuser/)

  • +
+

The Icarus Verilog support for the deprecated PLI-1 is in this +subdirectory. The vvp runtime does not directly support the +PLI-1. Instead, the libveriuser library emulates it using the builtin +PLI-2 support.

+
    +
  • The Cadence PLI module compatibility module (cadpli/)

  • +
+

It is possible in some specialized situations to load and execute +PLI-1 code written for Verilog-XL. This directory contains the source +for the module that provides the Cadence PLI interface.

+
+
+

The Core Compiler

+

The “ivl” binary is the core compiler that does the heavy lifting of +compiling the Verilog source (including libraries) and generating the +output. This is the most complex component of the Icarus Verilog +compilation system.

+

The process in the abstract starts with the Verilog lexical analysis +and parsing to generate an internal “pform”. The pform is then +translated by elaboration into the “netlist” form. The netlist is +processed by some functors (which include some optimizations and +optional synthesis) then is translated into the ivl_target internal +form. And finally, the ivl_target form is passed via the ivl_target.h +API to the code generators.

+
    +
  • Lexical Analysis

  • +
+

Lexical analysis and parsing use the tools “flex”, “gperf”, and +“bison”. The “flex” input file “lexor.lex” recognizes the tokens in +the input stream. This is called “lexical analysis”. The lexical +analyzer also does some processing of compiler directives that are not +otherwise taken care of by the external preprocessor. The lexical +analyzer uses a table of keywords that is generated using the “gperf” +program and the input file “lexor_keywords.gperf”. This table allows +the lexical analyzer to efficiently check input words with the rather +large set of potential keywords.

+
    +
  • Parsing

  • +
+

The parser input file “parse.y” is passed to the “bison” program to +generate the parser. The parser uses the functions in parse*.h, +parse*.cc, pform.h, and pform*.cc to generate the pform from the +stream of input tokens. The pform is what compiler writers call a +“decorated parse tree”.

+

The pform itself is described by the classes in the header files +“PScope.h”, “Module.h”, “PGenerate.h”, “Statement.h”, and +“PExpr.h”. The implementations of the classes in those header files +are in the similarly named C++ files.

+
    +
  • Elaboration

  • +
+

Elaboration transforms the pform to the netlist form. Elaboration is +conceptually divided into several major steps: Scope elaboration, +parameter overrides and defparam propagation, signal elaboration, and +statement and expression elaboration.

+

The elaboration of scopes and parameter overrides and defparam +propagation are conceptually separate, but are in practice +intermingled. The elaboration of scopes scans the pform to find and +instantiate all the scopes of the design. New scopes are created by +instantiation of modules (starting with the root instances) by user +defined tasks and functions, named blocks, and generate schemes. The +elaborate_scope methods implement scope elaboration, and the +elab_scope.cc source file has the implementations of those +methods.

+

The elaborate.cc source file contains the initial calls to the +elaborate_scope for the root scopes to get the process started. In +particular, see the “elaborate” function near the bottom of the +elaborate.cc source file. The calls to Design::make_root_scope create +the initial root scopes, and the creation and enqueue of the +elaborate_root_scope_t work items primes the scope elaboration work +list.

+

Intermingled in the work list are defparms work items that call the +Design::run_defparams and Design::evaluate_parameters methods that +override and evaluate parameters. The override and evaluation of +parameters must be intermingled with the elaboration of scopes because +the exact values of parameters may impact the scopes created (imagine +generate schemes and instance arrays) and the created scopes in turn +create new parameters that need override and evaluation.

+
+
+

Further Reading

+

For further information on the individual parts of Icarus Verilog, see this listing:

+ +
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/ivl/attributes.html b/developer/guide/ivl/attributes.html new file mode 100644 index 0000000000..df2a8f9b43 --- /dev/null +++ b/developer/guide/ivl/attributes.html @@ -0,0 +1,207 @@ + + + + + + + + + Icarus Verilog Attributes — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Icarus Verilog Attributes

+
+

Attribute Naming Conventions

+

Attributes that are specific to Icarus Verilog, and are intended to be +of use to programmers, start with the prefix “ivl_”.

+

Attributes with the “_ivl_” prefix are set aside for internal +use. They may be generated internally by the compiler. They need not +be documented here.

+
+
+

Attributes To Control Synthesis

+

The following is a summary of Verilog attributes that Icarus Verilog +understands within Verilog source files to control synthesis +behavior. This section documents generic synthesis attributes. For +target specific attributes, see target specific documentation.

+

These attributes only effect the behavior of the synthesizer. For +example, the ivl_combinational will not generate an error message +if the Verilog is being compiled for simulation. (It may generate a +warning.)

+
    +
  • Attributes for “always” and “initial” statements

  • +
+

(* ivl_combinational *)

+
+

This attribute tells the compiler that the statement models +combinational logic. If the compiler finds that it cannot make +combinational logic out of a marked always statement, it will +report an error.

+

This attribute can be used to prevent accidentally inferring +latches or flip-flops where the user intended combinational +logic.

+
+

(* ivl_synthesis_on *)

+
+

This attribute tells the compiler that the marked always statement +is synthesizable. The compiler will attempt to synthesize the +code in the marked “always” statement. If it cannot in any way +synthesize it, then it will report an error.

+
+

(* ivl_synthesis_off *)

+
+

If this value is attached to an “always” statement, then the +compiler will not synthesize the “always” statement. This can be +used, for example, to mark embedded test bench code.

+
+
    +
  • Attributes for modules

  • +
+

(* ivl_synthesis_cell *)

+
+

If this value is attached to a module during synthesis, that +module will be considered a target architecture primitive, and +its interior will not be synthesized further. The module can +therefore hold a model for simulation purposes.

+
+
    +
  • Attributes for signals (wire/reg/integer/tri/etc.)

  • +
+

(* PAD = “<pad assignment list>” *)

+
+

If this attribute is attached to a signal that happens to be a +root module port, then targets that support it will use the string +value as a list of pin assignments for the port/signal. The format +is a comma separated list of location tokens, with the format of +the token itself defined by the back-end tools in use.

+
+
    +
  • Other Attributes

  • +
+

[ none defined yet ]

+
+
+

Misc

+

(* _ivl_schedule_push *)

+
+

If this attribute is attached to a thread object (always or +initial statement) then the vvp code generator will generate code +that causes the scheduler to push this thread at compile time. The +compiler may internally add this attribute to always statements if +it detects that it is combinational. This helps resolve time-0 +races.

+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/ivl/index.html b/developer/guide/ivl/index.html new file mode 100644 index 0000000000..6006b55b7d --- /dev/null +++ b/developer/guide/ivl/index.html @@ -0,0 +1,132 @@ + + + + + + + + + IVL - The Core Compiler — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/ivl/ivl_target.html b/developer/guide/ivl/ivl_target.html new file mode 100644 index 0000000000..764cbea178 --- /dev/null +++ b/developer/guide/ivl/ivl_target.html @@ -0,0 +1,237 @@ + + + + + + + + + Loadable Target API (ivl_target) — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Loadable Target API (ivl_target)

+

In addition to the standard VPI API, Icarus Verilog supports a non-standard +loadable target module API. This API helps C programmers write modules that +Icarus Verilog can use to generate code. These modules are used at compile +time to write the elaborated design to the simulation or netlist files. For +example, the vvp code generator is a loadable target module that writes vvp +code into the specified file.

+

Loadable target modules gain access to the ‘elaborated’ design. That means, +the source files have been checked for syntax and correctness, any synthesis +and general optimization steps have been performed, and what is left is a +design that reflects but is not exactly the same as the input Verilog source +code. This relieves the modules of the burden of supporting all the odd +corners and complexities of the Verilog language.

+
+

The Target Module API

+

The API is defined in the header file “ivl_target.h” which is installed with +Icarus Verilog. The header defines the functions that the module writer can +use to get at the elaborated design during the course of writing the output +format.

+

The target module API function “target_design” is special in that the API does +not provide this function: The target module itself provides it. When the +compiler loads the target module, it invokes the “target_design” function with +a handle to the design. This is the point where the target module takes over +to process the design.

+
+
+

Compiling Target Modules

+

Compiling loadable target modules is similar to compiling VPI modules, in that +the module must be compiled with the “-fPIC” flag to gcc, and linked with the +“-shared” flag. The module that you compile is then installed in a place where +the “iverilog” command can find it, and configuration files are adjusted to +account for the new module.

+

This code:

+
# include  <ivl_target.h>
+
+int target_design(ivl_design_t des)
+{
+     return 0;
+}
+
+
+

is an example module that we can write into the file “empty.c”; and let us +compile it into the module file “empty.tgt” like so:

+
% gcc -o empty.tgt -fpic -shared empty.c
+
+
+

This makes the “empty.tgt” file an a dynamically loaded shared object.

+
+
+

Creating the Target Config File

+

The target config file tells the Icarus Verilog core how to process your new +code generator. The ivl core expects two configuration files: the name.conf +and the name-s.config files. The “-s” version is what is used if the user +gives the “-S” (synthesis) flag on the command line.

+

The stub target, included in most distributions, demonstrates the config +files. The “stub.conf” file is:

+
functor:cprop
+functor:nodangle
+-t:dll
+flag:DLL=stub.tgt
+
+
+

and the “stub-s.conf” file is:

+
functor:synth2
+functor:synth
+functor:syn-rules
+functor:cprop
+functor:nodangle
+-t:dll
+flag:DLL=stub.tgt
+
+
+

Note that the “stub-s.conf” file contains more lines to invoke internal +synthesis functions, whereas the “stub.conf” invokes only the basic +optimization steps.

+

In general, only the last line (The “flag:DLL=<name>.tgt” record) varies for +each target. For your target, replace the <name> with the name of your target +and you have a configuration file ready to install. Note that this is the name +of your target module. This is in fact how the config file tells the compiler +the name of your module.

+

The rest of the config file is best taken as boiler plate and installed as is, +with one difference. If your target is a synthesis target (for example a mosis +code generator or a pld code generator) that expects synthesis to happen, then +it makes the most sense to create both your config file like the “stub-s.conf” +config file. This causes the compiler to do synthesis for your target whether +the user gives the “-S” flag or not.

+
+
+

Installing the Target Module

+

Finally, the “empty.conf”, the “empty-s.conf” and the “empty.tgt” files need +to be installed. Where they go depends on your system, but in Linux they are +normally installed in “/usr/lib/ivl”.

+
+
+

LPM Devices

+

All LPM devices support a small set of common LPM functions, as +described in the ivl_target header file. The ivl_lpm_t object has a +type enumerated by ivl_lpm_type_t, and that type is accessible via the +ivl_lpm_type function.

+

The following are type specific aspects of LPM devices.

+
    +
  • IVL_LPM_UFUNC

  • +
+

This LPM represents a user defined function. It is a way to connect +behavioral code into a structural network. The UFUNC device has a +vector output and a set of inputs. The ivl_lpm_define function returns +the definition as an ivl_scope_t object.

+

The output vector is accessible through the ivl_lpm_q, and the output +has the width defined by ivl_lpm_width. This similar to most every +other LPM device with outputs.

+

There are ivl_lpm_size() input ports, each with the width +ivl_lpm_data2_width(). The actual nexus is indexed by ivl_lpm_data2().

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/ivl/lpm.html b/developer/guide/ivl/lpm.html new file mode 100644 index 0000000000..a311d50a6c --- /dev/null +++ b/developer/guide/ivl/lpm.html @@ -0,0 +1,146 @@ + + + + + + + + + What Is LPM — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

What Is LPM

+

LPM (Library of Parameterized Modules) is EIS-IS standard 103-A. It is +a standard library of abstract devices that are designed to be close +enough to the target hardware to be easily translated, yet abstract +enough to support a variety of target technologies without excessive +constraints. Icarus Verilog uses LPM internally to represent idealized +hardware, especially when doing target neutral synthesis.

+

In general, the user does not even see the LPM that Icarus Verilog +generates, because the LPM devices are translated into technology +specific devices by the final code generator or target specific +optimizers.

+
+

Internal Uses Of LPM

+

Internally, Icarus Verilog uses LPM devices to represent the design in +abstract, especially when synthesizing such functions as addition, +flip-flops, etc. The synth functor generates LPM modules when +interpreting procedural constructs. The functor generates the LPM +objects needed to replace a behavioral description, and uses +attributes to tag the devices with LPM properties.

+

Code generators need to understand the supported LPM devices so that +they can translate the devices into technology specific devices.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/ivl/netlist.html b/developer/guide/ivl/netlist.html new file mode 100644 index 0000000000..6d189a2aff --- /dev/null +++ b/developer/guide/ivl/netlist.html @@ -0,0 +1,366 @@ + + + + + + + + + Netlist Format — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Netlist Format

+

The output from the parse and elaboration steps is a “netlist” rooted +in a Design object. Parsing translates the design described in the +initial source file into a temporary symbolic “pform”. Elaboration +then expands the design, resolving references and expanding +hierarchies, to produce a flattened netlist. This is the form that +optimizers and code generators use.

+

The design optimization processes all manipulate the netlist, +translating it to a (hopefully) better netlist after each step. The +complete netlist is then passed to the code generator, the emit +function, where the final code (in the target format) is produced.

+
+

Structural Items: NetNode and NetNet

+

Components and wires, memories and registers all at their base are +either NetNode objects or NetNet objects. Even these classes are +derived from the NetObj class.

+

All NetNode and NetNet objects have a name and some number of +pins. The name usually comes from the Verilog source that represents +that object, although objects that are artifacts of elaboration will +have a generated (and probably unreadable) name. The pins are the +ports into the device. NetNode objects have a pin for each pin of the +component it represents, and NetNet objects have a pin for each signal +in the vector.

+

Node and net pins can be connected together via the connect +function. Connections are transitive (A==B and B==c means A==C) so +connections accumulate on a link as items are connected to it. The +destructors for nets and nodes automatically arrange for pins to be +disconnected when the item is deleted, so that the netlist can be +changed during processing.

+
+ +
+

Behavioral Items: NetProcTop, NetProc and derived classes

+

Behavioral items are not in general linked to the netlist. Instead, +they represent elaborated behavioral statements. The type of the object +implies what the behavior of the statement does. For example, a +NetCondit object represents an if statement, and carries a +condition expression and up to two alternative sub-statements.

+

At the root of a process is a NetProcTop object. This class carries a +type flag (initial or always) and a single NetProc object. The +contained statement may, depending on the derived class, refer to +other statements, compound statements, so on. But at the root of the +tree is the NetProcTop object. The Design class keeps a list of the +elaborated NetProcTop objects. That list represents the list of +processes in the design.

+
+
+

Interaction Of Behavioral And Structural: NetAssign_

+

The behavioral statements in a Verilog design effect the structural +aspects through assignments to registers. Registers are structural +items represented by the NetNet class, linked to the assignment +statement through pins. This implies that the l-value of an assignment +is structural. It also implies that the statement itself is +structural, and indeed it is derived from NetNode.

+

The NetAssign_ class is also derived from the NetProc class because +what it does is brought on by executing the process. By multiple +inheritance we have therefore that the assignment is both a NetNode +and a NetProc. The NetAssign_ node has pins that represent the l-value +of the statement, and carries behavioral expressions that represent +the r-value of the assignment.

+
+
+

Memories

+

The netlist form includes the NetMemory type to hold the content of a +memory. Instances of this type represent the declaration of a memory, +and occur once for each memory. References to the memory are managed +by the NetEMemory and NetAssignMem_ classes.

+

An instance of the NetEMemory class is created whenever a procedural +expression references a memory element. The operand is the index to +use to address (and read) the memory.

+

An instance of the NetAssignMem_ class is created when there is a +procedural assignment to the memory. The NetAssignMem_ object +represents the l-value reference (a write) to the memory. As with the +NetEMemory class, this is a procedural reference only.

+

When a memory reference appears in structural context (i.e. continuous +assignments) elaboration creates a NetRamDq. This is a LPM_RAM_DQ +device. Elaboration leaves the write control and data input pins +unconnected for now, because memories cannot appear is l-values of +continuous assignments. However, the synthesis functor may connect +signals to the write control lines to get a fully operational RAM.

+

By the time elaboration completes, there may be many NetAssignMem_, +NetEMemory and NetRamDq objects referencing the same NetMemory +object. Each represents a port into the memory. It is up to the +synthesis steps (and the target code) to figure out what to do with +these ports.

+
+
+

Expressions

+

Expressions are represented as a tree of NetExpr nodes. The NetExpr +base class contains the core methods that represent an expression +node, including virtual methods to help with dealing with nested +complexities of expressions.

+

Expressions (as expressed in the source and p-form) may also be +elaborated structurally, where it makes sense. For example, assignment +l-value expressions are represented as connections to pins. Also, +continuous assignment module items are elaborated as gates instead of +as a procedural expression. Event expressions are also elaborated +structurally as events are like devices that trigger behavioral +statements.

+

However, typical expressions the behavioral description are +represented as a tree of NetExpr nodes. The derived class of the node +encodes what kind of operator the node represents.

+
+
+

Expression Bit Width

+

The expression (represented by the NetExpr class) has a bit width that +it either explicitly specified, or implied by context or contents. +When each node of the expression is first constructed during +elaboration, it is given, by type and parameters, an idea what its +width should be. It certain cases, this is definitive, for example +with signals. In others, it is ambiguous, as with unsized constants.

+

As the expression is built up by elaboration, operators that combine +expressions impose bit widths of the environment or expose the bit +widths of the sub expressions. For example, the bitwise AND (&) +operator has a bit size implied by its operands, whereas the +comparison (==) operator has a bit size of 1. The building up of the +elaborated expression checks and adjusts the bit widths as the +expression is built up, until finally the context of the expression +takes the final bit width and makes any final adjustments.

+

The NetExpr::expr_width() method returns the calculated (or guessed) +expression width. This method will return 0 until the width is set by +calculation or context. If this method returns false, then it is up to +the context that wants the width to set one. The elaboration phase +will call the NetExpr::set_width method on an expression as soon as it +gets to a point where it believes that it knows what the width should +be.

+

The NetExpr::set_width(unsigned) virtual method is used by the context +of an expression node to note to the expression that the width is +determined and please adapt. If the expression cannot reasonably +adapt, it will return false. Otherwise, it will adjust bit widths and +return true.

+
I do not yet properly deal with cases where elaboration knows for
+certain that the bit width does not matter. In this case, I
+really should tell the expression node about it so that it can
+pick a practical (and optimal) width.
+
+
+
+
+

Interaction Of Expressions And Structure: NetESignal

+

The NetAssign_ class described above is the means for processes to +manipulate the net, but values are read from the net by NetESignal +objects. These objects are class NetExpr because they can appear in +expressions (and have width). They are not NetNode object, but hold +pointers to a NetNet object, which is used to retrieve values with the +expression is evaluated.

+
+
+

Hierarchy In Netlists

+

The obvious hierarchical structure of Verilog is the module. The +Verilog program may contain any number of instantiations of modules in +order to form an hierarchical design. However, the elaboration of the +design into a netlist erases module boundaries. Modules are expanded +each place they are used, with the hierarchical instance name used to +name the components of the module instance. However, the fact that a +wire or register is a module port is lost.

+

The advantage of this behavior is first the simplification of the +netlist structure itself. Backends that process netlists only need to +cope with a list of nets, a list of nodes and a list of +processes. This eases the task of the backend code generators.

+

Another advantage of this flattening of the netlist is that optimizers +can operate globally, with optimizations freely crossing module +boundaries. This makes coding of netlist transform functions such as +constant propagation more effective and easier to write.

+
+
+

Scope Representation In Netlists

+

In spite of the literal flattening of the design, scope information is +preserved in the netlist, with the NetScope class. The Design class +keeps a single pointer to the root scope of the design. This is the +scope of the root module. Scopes that are then created within that +(or any nested) module are placed as children of the root scope, and +those children can have further children, and so on.

+

Each scope in the tree carries its own name, and its relationship to +its parent and children. This makes it possible to walk the tree of +scopes. In practice, the walking of the scopes is handled by recursive +methods.

+

Each scope also carries the parameters that are applicable to the +scope itself. The parameter expression (possibly evaluated) can be +located by name, given the scope object itself. The scan of the pform +to generate scopes also places the parameters that are declared in the +scope. Overrides are managed during the scan, and once the scan is +complete, defparam overrides are applied.

+
+
+

Tasks In Netlists

+

The flattening of the design does not include tasks and named +begin-end blocks. Tasks are behavioral hierarchy (whereas modules are +structural) so do not easily succumb to the flattening process. In +particular, it is logically impossible to flatten tasks that +recurse. (The elaboration process does reserve the right to flatten +some task calls. C++ programmers recognize this as inlining a task.)

+
+
+

Time Scale In Netlists

+

The Design class and the NetScope classes carry time scale and +resolution information of the elaborated design. There is a global +resolution, and there are scope specific units and resolutions. Units +and resolutions are specified as signed integers, and interpreted as +the power of 10 of the value. For example, a resolution “-9” means +that “1” is 1ns (1e-9). The notation supports units from -128 to +127. +It is up to the back-ends to interpret “-4” as “100us”.

+

Delays are expressed in the netlist by integers. The units of these +delays are always given in the units of the design precision. This +allows everything to work with integers, and generally places the +burden of scaling delays into elaboration. This is, after all, a +common task. The Design::get_precision() method gets the global design +precision.

+

Each NetScope also carries its local time_units and time_precision +values. These are filled in during scope elaboration and are used in +subsequent elaboration phases to arrange for scaling of delays. This +information can also be used by the code generator to scale times back +to the units of the scope, if that is desired.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/ivl/t-dll.html b/developer/guide/ivl/t-dll.html new file mode 100644 index 0000000000..9f90dc6a92 --- /dev/null +++ b/developer/guide/ivl/t-dll.html @@ -0,0 +1,175 @@ + + + + + + + + + Loadable Targets — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Loadable Targets

+

Icarus Verilog supports dynamically loading code generator modules to +perform the back-end processing of the completed design. The user +specifies on the command line the module to load. The compiler loads +the module (once the design is compiled and elaborated) and calls it +to finally handle the design.

+

Loadable target modules implement a set of functions that the core +compiler calls to pass the design to it, and the module in turn uses a +collection of functions in the core (the API) to access details of the +design.

+
+

Loading Target Modules

+

The target module loader is invoked with the ivl flag “-tdll”. That +is, the DLL loader is a linked in target type. The name of the target +module to load is then specified with the DLL flag, i.e. “-fDLL=<path>”.

+
+
+

Compiling Target Modules

+

<write me>

+
+
+

Loadable Target Module Api

+

The target module API is defined in the ivl_target.h header file. This +declares all the type and functions that a loadable module needs to +access the design.

+
+
+

About Specific Expression Types

+

In this section find notes about the various kinds of expression +nodes. The notes here are in addition to the more general +documentation in the ivl_target.h header file.

+
    +
  • IVL_EX_CONCAT

    +

    The concatenation operator forms an expression node that holds the +repeat count and all the parameter expressions. The repeat count is +an integer that is calculated by the core compiler so it fully +evaluated, and not an expression.

    +

    The parameter expressions are retrieved by the ivl_expr_parm method, +with the index increasing as parameters go from left to right, from +most significant to least significant. (Note that this is different +from the order of bits within an expression node.)

    +
  • +
  • IVL_EX_NUMBER

    +

    This is a constant number. The width is fully known, and the bit +values are all represented by the ASCII characters 0, 1, x or z. The +ivl_expr_bits method returns a pointer to the least significant bit, +and the remaining bits are ordered from least significant to most +significant. For example, 5’b1zzx0 is the 5 character string “0xzz1”.

    +
  • +
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/misc/ieee1364-notes.html b/developer/guide/misc/ieee1364-notes.html new file mode 100644 index 0000000000..0b5b07b0c7 --- /dev/null +++ b/developer/guide/misc/ieee1364-notes.html @@ -0,0 +1,578 @@ + + + + + + + + + IEEE1364 Notes — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

IEEE1364 Notes

+

The IEEE1364 standard is the bible that defines the correctness of the +Icarus Verilog implementation and behavior of the compiled +program. The IEEE1364.1 is also referenced for matters of +synthesis. So the ultimate definition of right and wrong comes from +those documents.

+

That does not mean that a Verilog implementation is fully +constrained. The standard document allows for implementation specific +behavior that, when properly accounted for, does not effect the +intended semantics of the specified language. It is therefore possible +and common to write programs that produce different results when run +by different Verilog implementations.

+
+

Standardization Issues

+

These are some issues where the IEEE1364 left unclear, unspecified or +simply wrong. I’ll try to be precise as I can, and reference the +standard as needed. I’ve made implementation decisions for Icarus +Verilog, and I will make clear what those decisions are and how they +affect the language.

+
    +
  • OBJECTS CAN BE DECLARED ANYWHERE IN THE MODULE

  • +
+

Consider this module:

+
module sample1;
+    initial foo = 1;
+reg foo;
+wire tmp = bar;
+initial #1 $display("foo = %b, bar = %b", foo, tmp);
+endmodule
+
+
+

Notice that the reg foo; declaration is placed after the first +initial statement. It turns out that this is a perfectly legal module +according to the -1995 and -2000 versions of the standard. The +statement reg foo; is a module_item_declaration which is in turn a +module_item. The BNF in the appendix of IEEE1364-1995 treats all +module_item statements equally, so no order is imposed.

+

Furthermore, there is no text (that I can find) elsewhere in the +standard that imposes any ordering restriction. The sorts of +restrictions I would look for are “module_item_declarations must +appear before all other module_items” or “variables must be declared +textually before they are referenced.” Such statements simply do not +exist. (Personally, I think it is fine that they don’t.)

+

The closest is the rules for implicit declarations of variables that +are otherwise undeclared. In the above example, bar is implicitly +declared and is therefore a wire. However, although initial foo = 1; +is written before foo is declared, foo is declared within the +module, and declared legally by the BNF of the standard.

+

Here is another example:

+
module sample2;
+    initial x.foo = 1;
+    test x;
+    initial #1 $display("foo = %b", x.foo);
+endmodule
+
+module test;
+    reg foo;
+endmodule;
+
+
+

From this example one can clearly see that foo is once again declared +after its use in behavioral code. One also sees a forward reference of +an entire module. Once again, the standard places no restriction on +the order of module declarations in a source file, so this program is, +according to the standard, perfectly well formed.

+

Icarus Verilog interprets both of these examples according to “The +Standard As I Understand It.” However, commercial tools in general +break down with these programs. In particular, the first example +may generate different errors depending on the tool. The most common +error is to claim that foo is declared twice, once (implicitly) as +a wire and once as a reg.

+

So the question now becomes, “Is the standard broken, or are the tools +limited?” Coverage of the standard seems to vary widely from tool to +tool so it is not clear that the standard really is at fault. It is +clear, however, that somebody goofed somewhere.

+

My personal opinion is that there is no logical need to require that +all module_item_declarations precede any other module items. I +personally would oppose such a restriction. It may make sense to +require that declarations of variables within a module be preceded by +their use, although even that is not necessary for the implementation +of efficient compilers.

+

However, the existence hierarchical naming syntax as demonstrated in +sample2 can have implications that affect any declaration order +rules. When reaching into a module with a hierarchical name, the +module being referenced is already completely declared (or not +declared at all, as in sample2) so module_item order is completely +irrelevant. But a “declare before use” rule would infect module +ordering, by requiring that modules that are used be first defined.

+
    +
  • TASK AND FUNCTION PARAMETERS CANNOT HAVE EXPLICIT TYPES

  • +
+

Consider a function negate that wants to take a signed integer value +and return its negative:

+
function integer negate;
+    input [15:0] val;
+    negate = -val;
+endfunction
+
+
+

This is not quite right, because the input is implicitly a reg type, +which is unsigned. The result, then, will always be a negative value, +even if a negative val is passed in.

+

It is possible to fix up this specific example to work properly with +the bit pattern of a 16bit number, but that is not the point. What’s +needed is clarification on whether an input can be declared in the +port declaration as well as in the contained block declaration.

+

As I understand the situation, this should be allowed:

+
function integer negate;
+    input [15:0] val;
+    reg signed [15:0] val;
+    negate = -val;
+endfunction
+
+
+

In the -1995 standard, the variable is already implicitly a reg if +declared within a function or task. However, in the -2000 standard +there is now (as in this example) a reason why one might want to +actually declare the type explicitly.

+

I think that a port cannot be declared as an integer or time type +(though the result can) because the range of the port declaration must +match the range of the integer/time declaration, but the range of +integers is unspecified. This, by the way, also applies to module +ports.

+

With the above in mind, I have decided to allow function and task +ports to be declared with types, as long as the types are variable +types, such as reg or integer. Without this, there would be no +portable way to pass integers into functions/tasks. The standard does +not say it is allowed, but it doesn’t disallow it, and other +commercial tools seem to work similarly.

+
    +
  • ROUNDING OF TIME

  • +
+

When the `timescale directive is present, the compiler is supposed to +round fractional times (after scaling) to the nearest integer. The +confusing bit here is that it is apparently conventional that if the +`timescale directive is not present, times are rounded towards zero +always.

+
    +
  • VALUE OF X IN PRIMITIVE OUTPUTS

  • +
+

The IEEE1364-1995 standard clearly states in Table 8-1 that the x +symbols is allowed in input columns, but is not allowed in +outputs. Furthermore, none of the examples have an x in the output of +a primitive. Table 8-1 in the IEEE1364-2000 also says the same thing.

+

However, the BNF clearly states that 0, 1, x and X are valid +output_symbol characters. The standard is self contradictory. So I +take it that x is allowed, as that is what Verilog-XL does.

+
    +
  • REPEAT LOOPS vs. REPEAT EVENT CONTROL

  • +
+

There seems to be ambiguity in how code like this should be parsed:

+
repeat (5) @(posedge clk) <statement>;
+
+
+

There are two valid interpretations of this code, from the +IEEE1364-1995 standard. One looks like this:

+
procedural_timing_control_statement ::=
+      delay_or_event_control  statement_or_null
+
+delay_or_event_control ::=
+      event_control
+      | repeat ( expression ) event_control
+
+
+

If this interpretation is used, then the statement <statement> should +be executed after the 5th posedge of clk. However, there is also this +interpretation:

+
loop_statement ::=
+     repeat ( expression ) statement
+
+
+

If this interpretation is used, then <statement> should be executed +5 times on the posedge of clk. The way the -1995 standard is written, +these are both equally valid interpretations of the example, yet they +produce very different results. The standard offers no guidance on how +to resolve this conflict, and the IEEE1364-2000 DRAFT does not improve +the situation.

+

Practice suggests that a repeat followed by an event control should be +interpreted as a loop head, and this is what Icarus Verilog does, as +well as all the other major Verilog tools, but the standard does not +say this.

+
    +
  • UNSIZED NUMERIC CONSTANTS ARE NOT LIMITED TO 32 BITS

  • +
+

The Verilog standard allows Verilog implementations to limit the size +of unsized constants to a bit width of at least 32. That means that a +constant 17179869183 (36’h3_ffff_ffff) may overflow some compilers. In +fact, it is common to limit these values to 32bits. However, a +compiler may just as easily choose another width limit, for example +64bits. That value is equally good.

+

However, it is not required that an implementation truncate at 32 +bits, and in fact Icarus Verilog does not truncate at all. It will +make the unsized constant as big as it needs to be to hold the value +accurately. This is especially useful in situations like this:

+
reg [width-1:0] foo = 17179869183;
+
+
+

The programmer wants the constant to take on the width of the reg, +which in this example is parameterized. Since constant sizes cannot be +parameterized, the programmer ideally gives an unsized constant, which +the compiler then expands/contracts to match the l-value.

+

Also, by choosing to not ever truncate, Icarus Verilog can handle code +written for a 64bit compiler as easily as for a 32bit compiler. In +particular, any constants that the user does not expect to be +arbitrarily truncated by his compiler will also not be truncated by +Icarus Verilog, no matter what that other compiler chooses as a +truncation point.

+
    +
  • UNSIZED EXPRESSIONS AS PARAMETERS TO CONCATENATION {}

  • +
+

The Verilog standard clearly states in 4.1.14:

+
"Unsized constant numbers shall not be allowed in
+concatenations. This is because the size of each
+operand in the concatenation is needed to calculate
+the complete size of the concatenation."
+
+
+

So for example the expression {1’b0, 16} is clearly illegal. It +also stands to reason that {1’b0, 15+1} is illegal, for exactly the +same justification. What is the size of the expression (15+1)? +Furthermore, it is reasonable to expect that (16) and (15+1) are +exactly the same so far as the compiler is concerned.

+

Unfortunately, Cadence seems to feel otherwise. In particular, it has +been reported that although {1’b0, 16} causes an error, {1’b0, 15+1} +is accepted. Further testing shows that any expression other than a +simple unsized constant is accepted there, even if all the operands of +all the operators that make up the expression are unsized integers.

+

This is a semantic problem. Icarus Verilog doesn’t limit the size of +integer constants. This is valid as stated in 2.5.1 Note 3:

+
"The number of bits that make up an unsized number
+(which is a simple decimal number or a number without
+the size specification) shall be *at*least* 32."
+[emphasis added]
+
+
+

Icarus Verilog will hold any integer constant, so the size will be as +large as it needs to be, whether that is 64bits, 128bits, or +more. With this in mind, what is the value of these expressions?

+
{'h1_00_00_00_00}
+{'h1 << 32}
+{'h0_00_00_00_01 << 32}
+{'h5_00_00_00_00 + 1}
+
+
+

These examples show that the standard is justified in requiring that +the operands of concatenation have size. The dispute is what it takes +to cause an expression to have a size, and what that size is. +Verilog-XL claims that (16) does not have a size, but (15+1) does. The +size of the expression (15+1) is the size of the adder that is +created, but how wide is the adder when adding unsized constants?

+

One might note that the quote from section 4.1.14 says “Unsized +constant*numbers shall not be allowed.” It does not say “Unsized +expressions…”, so arguably accepting (15+1) or even (16+0) as an +operand to a concatenation is not a violation of the letter of the +law. However, the very next sentence of the quote expresses the +intent, and accepting (15+1) as having a more defined size than (16) +seems to be a violation of that intent.

+

Whatever a compiler decides the size is, the user has no way to +predict it, and the compiler should not have the right to treat (15+1) +any differently than (16). Therefore, Icarus Verilog takes the +position that such expressions are unsized and are not allowed as +operands to concatenations. Icarus Verilog will in general assume that +operations on unsized numbers produce unsized results. There are +exceptions when the operator itself does define a size, such as the +comparison operators or the reduction operators. Icarus Verilog will +generate appropriate error messages.

+
    +
  • MODULE INSTANCE WITH WRONG SIZE PORT LIST

  • +
+

A module declaration like this declares a module that takes three ports:

+
module three (a, b, c);
+  input a, b, c;
+  reg x;
+endmodule
+
+
+

This is fine and obvious. It is also clear from the standard that +these are legal instantiations of this module:

+
three u1 (x,y,z);
+three u2 ( ,y, );
+three u3 ( , , );
+three u4 (.b(y));
+
+
+

In some of the above examples, there are unconnected ports. In the +case of u4, the pass by name connects only port b, and leaves a and c +unconnected. u2 and u4 are the same thing, in fact, but using +positional or by-name syntax. The next example is a little less +obvious:

+
three u4 ();
+
+
+

The trick here is that strictly speaking, the parser cannot tell +whether this is a list of no pass by name ports (that is, all +unconnected) or an empty positional list. If this were an empty +positional list, then the wrong number of ports is given, but if it is +an empty by-name list, it is an obviously valid instantiation. So it +is fine to accept this case as valid.

+

These are more doubtful:

+
three u5(x,y);
+three u6(,);
+
+
+

These are definitely positional port lists, and they are definitely +the wrong length. In this case, the standard is not explicit about +what to do about positional port lists in module instantiations, +except that the first is connected to the first, second to second, +etc. It does not say that the list must be the right length, but every +example of unconnected ports used by-name syntax, and every example of +ordered list has the right size list.

+

Icarus Verilog takes the (very weak) hint that ordered lists should be +the right length, and will therefore flag instances u5 and u6 as +errors. The IEEE1364 standard should be more specific one way or the +other.

+
    +
  • UNKNOWN VALUES IN L-VALUE BIT SELECTS

  • +
+

Consider this example:

+
reg [7:0] vec;
+wire [4:0] idx = <expr>;
+[...]
+vec[idx] = 1;
+
+
+

So long as the value of idx is a valid bit select address, the +behavior of this assignment is obvious. However, there is no explicit +word in the standard as to what happens if the value is out of +range. The standard clearly states the value of an expression when the +bit-select or part select is out of range (the value is x) but does +not address the behavior when the expression is an l-value.

+

Icarus Verilog will take the position that bit select expressions in +the l-value will select oblivion if it is out of range. That is, if +idx has a value that is not a valid bit select of vec, then the +assignment will have no effect.

+
    +
  • SCHEDULING VALUES IN LOGIC

  • +
+

The interaction between blocking assignments in procedural code and +logic gates in gate-level code and expressions is poorly defined in +Verilog. Consider this example:

+
reg a;
+reg b;
+wire q = a & b;
+
+initial begin
+   a = 1;
+   b = 0;
+   #1 b = 1;
+   if (q !== 0) begin
+      $display("FAILED -- q changed too soon? %b", q);
+      $finish;
+   end
+end
+
+
+

This is a confusing situation. It is clear from the Verilog standard +that an assignment to a variable using a blocking assign causes the +l-value to receive the value before the assignment completes. This +means that a subsequent read of the assigned variable must read back +what was blocking-assigned.

+

However, in the example above, the “wire q = a & b” expresses some +gate logic between a/b and q. The standard does not say whether a read +out of logic should read the value computed from previous assigns to +the input from the same thread. Specifically, when “a” and “b” are +assigned by blocking assignments, will a read of “q” get the computed +value or the existing value?

+

In fact, existing commercial tools do it both ways. Some tools print +the FAILED message in the above example, and some do not. Icarus +Verilog does not print the FAILED message in the above example, +because the gate value change is scheduled when inputs are assigned, +but not propagated until the thread gives up the processor.

+

Icarus Verilog chooses this behavior in order to filter out zero-width +pulses as early as possible. The implication of this is that a read of +the output of combinational logic will most likely not reflect the +changes in inputs until the thread that changed the inputs yields +execution.

+
    +
  • BIT AND PART SELECTS OF PARAMETERS

  • +
+

Bit and part selects are supposed to only be supported on vector nets +and variables (wires, regs, etc.) However, it is common for Verilog +compilers to also support bit and part select on parameters. Icarus +Verilog also chooses to support bit and part selects on parameter +names, but we need to define what that means.

+

A bit or a part select on a parameter expression returns an unsigned +value with a defined size. The parameter value is considered be a +constant vector of bits foo[X:0]. That is, zero based. The bit and +part selects operate from that assumption.

+

Verilog 2001 adds syntax to allow the user to explicitly declare the +parameter range (i.e. parameter [5:0] foo = 9;) so Icarus Verilog will +(or should) use the explicitly declared vector dimensions to interpret +bit and part selects.

+
    +
  • EDGES OF VECTORS

  • +
+

Consider this example:

+
reg [ 5:0] clock;
+always @(posedge clock) [do stuff]
+
+
+

The IEEE1364 standard clearly states that the @(posedge clock) looks +only at the bit clock[0] (the least significant bit) to search for +edges. It has been pointed out by some that Verilog XL instead +implements it as @(posedge |clock): it looks for a rise in the +reduction or of the vector. Cadence Design Systems technical support +has been rumored to claim that the IEEE1364 specification is wrong, +but NC-Verilog behaves according to the specification, and thus +different from XL.

+

Icarus Verilog, therefore, takes the position that the specification +is clear and correct, and it behaves as does NC-Verilog in this +matter.

+
    +
  • REAL VARIABLES IN $dumpoff DEAD-ZONES

  • +
+

The IEEE1364 standard clearly states that in VCD files, the $dumpoff +section checkpoints all the dumped variables as X values. For reg and +wire bits/vectors, this obviously means ‘bx values. Icarus Verilog +does this, for example:

+
$dumpoff
+x!
+x"
+$end
+
+
+

Real variables can also be included in VCD dumps, but it is not at +all obvious what is supposed to be dumped into the $dumpoff-$end +section of the VCD file. Verilog-XL dumps “r0 !” to set the real +variables to the dead-zone value of 0.0, whereas other tools, such as +ModelTech, ignore real variables in this section.

+

For example (from XL):

+
$dumpoff
+r0 !
+r0 "
+$end
+
+
+

Icarus Verilog dumps NaN values for real variables in the +$dumpoff-$end section of the VCD file. The NaN value is the IEEE754 +equivalent of an unknown value, and so better reflects the unknown +(during the dead zone) status of the variable, like this:

+
$dumpoff
+rNaN !
+rNaN "
+$end
+
+
+

It turns out that NaN is conventionally accepted by scanf functions, +and viewers that support real variables support NaN values. So while +the IEEE1364 doesn’t require this behavior, and given the variety that +already seems to exist amongst VCD viewers in the wild, this behavior +seems to be acceptable according to the standard, is a better mirror +of 4-value behavior in the dead zone, and appears more user friendly +when viewed by reasonable viewers.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/misc/index.html b/developer/guide/misc/index.html new file mode 100644 index 0000000000..20f3d5ebc6 --- /dev/null +++ b/developer/guide/misc/index.html @@ -0,0 +1,130 @@ + + + + + + + + + Miscellaneous — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Miscellaneous

+ +
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/misc/swift.html b/developer/guide/misc/swift.html new file mode 100644 index 0000000000..b3b8f49591 --- /dev/null +++ b/developer/guide/misc/swift.html @@ -0,0 +1,191 @@ + + + + + + + + + Swift Model Support (Preliminary) — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Swift Model Support (Preliminary)

+
+
+

Copyright 2003-2024 Stephen Williams

+
+

NOTE: SWIFT support does not work yet, these are provisional +instructions, intended to show what’s supposed to happen when I get +it working.

+
+

Icarus Verilog support for SWIFT models is based on the LMTV interface +module from Synopsys. This module is normally distributed along with +the SWIFT models proper. This module can be linked with Icarus Verilog +via the cadpli compatibility object. (See cadpli.txt.)

+
    +
  • Preliminaries

  • +
+

First, you need the LMC_HOME environment variable set to point to the +installed directory for your SWIFT software. This setup is documented +in your SWIFT model documentation.

+
    +
  • Compilation

  • +
+

When compiling your Verilog design to include a SWIFT model, you need +to include wrappers for the model you intend to use. You may choose to +use ncverilog or verilogxl compatible wrappers, they work the +same. Locate your smartmodel directory, and include it in your command +file like so:

+
+libdir+.../smartmodel/sol/wrappers/verilogxl
+
+
+

The wrappers directory includes Verilog modules that wrap your SWIFT +module, and with this +libdir+ statement in your command file, the +Icarus Verilog compiler will be able to locate these wrappers. The +wrappers in turn invoke the $lm_model system tasks that are the LMTV +support for your model.

+
+

NOTE: This example uses the solaris directory of VerilogXL support +files as a source of wrappers. The files of interest, however, are +written in Verilog and are identical for all supported platforms, so +long as you choose the verilogxl or ncverilog files.

+
+
    +
  • Execution

  • +
+

After your simulation is compiled, run the simulation with the vvp +command, like this:

+
% vvp -mcadpli a.out -cadpli=$LMC_HOME/lib/x86_linux.lib/swiftpli.so:swift_boot
+
+
+

What this command line means is:

+
-mcadpli
+   Include the cadpli compatibility module
+
+a.out
+   This is your compiled vvp file
+
+-cadpli=$LMC_HOME/lib/x86_linux.lib/swiftpli.so:swift_boot
+   This tells the cadpli module to load the swiftpli.so
+   shared object, and boot it. This is code that comes with
+   your SWIFT modules, and provides the generic SWIFT
+   capabilities (lm_* system tasks) needed by the module
+   itself.
+
+
+

Once you start the vvp command, the SWIFT infrastructure will be +initialized as part of the simulation setup, and all should work +normally from here.

+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/misc/xilinx-hint.html b/developer/guide/misc/xilinx-hint.html new file mode 100644 index 0000000000..32bd9b40c9 --- /dev/null +++ b/developer/guide/misc/xilinx-hint.html @@ -0,0 +1,228 @@ + + + + + + + + + Xilinx Hint — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Xilinx Hint

+

For those of you who wish to use Icarus Verilog, in combination with +the Xilinx back end (Foundation or Alliance), it can be done. I have +run some admittedly simple (2300 equivalent gates) designs through this +setup, targeting a Spartan XCS10.

+
+

Verilog:

+

Older versions of Icarus Verilog (like 19990814) couldn’t synthesize +logic buried in procedural (flip-flop) assignment. Newer versions +(like 20000120) don’t have this limitation.

+

Procedural assignments have to be given one at a time, to be +“found” by xnfsyn. Say

+
always @ (posedge Clk) Y = newY;
+always @ (posedge Clk) Z = newZ;
+
+
+

rather than

+
always @ (posedge Clk) begin
+    Y = newY;
+    Z = newZ;
+end
+
+
+

Steve’s xnf.txt covers most buffer and pin constructs, but I had reason +to use a global clock net not connected to an input pin. The standard +Verilog for a buffer, combined with a declaration to turn that into a +BUFG, is:

+
buf BUFG( your_output_here, your_input_here );
+$attribute(BUFG,"XNF-LCA","BUFG:O,I")
+
+
+

I use post-processing on my .xnf files to add “FAST” attributes to +output pins.

+
+
+

Running ivl:

+

The -F switches are important. The following order seems to robustly +generate valid XNF files, and is used by “verilog -X”:

+
-Fsynth -Fnodangle -Fxnfio
+
+
+
+
+

Generating .pcf files:

+

The ngdbuild step seems to lose pin placement information that ivl +puts in the XNF file. Use xnf2pcf to extract this information to +a .pcf file, which the Xilinx place-and-route software _will_ pay +attention to. Steve says he now makes that information available +in an NCF file, with -fncf=<path>, but I haven’t tested that.

+

Running the Xilinx back end:

+

You can presumably use the GUI, but that doesn’t fit in Makefiles :-). +Here is the command sequence in pseudo-shell-script:

+
ngdbuild -p $part $1.xnf $1.ngd
+map -p $part -o map.ncd $1.ngd
+xnf2pcf <$1.xnf >$1.pcf    # see above
+par -w -ol 2 -d 0 map.ncd $1.ncd $1.pcf
+bitgen_flags = -g ConfigRate:SLOW -g TdoPin:PULLNONE -g DonePin:PULLUP \
+               -g CRC:enable -g StartUpClk:CCLK -g SyncToDone:no \
+               -g DoneActive:C1 -g OutputsActive:C3 -g GSRInactive:C4 \
+               -g ReadClk:CCLK -g ReadCapture:enable -g ReadAbort:disable
+bitgen $1.ncd -l -w $bitgen_flags
+
+
+

The Xilinx software has diarrhea of the temp files (14, not including +.xnf, .pcf, .ngd, .ncd, and .bit), so this sequence is best done in a +dedicated directory. Note in particular that map.ncd is a generic name.

+

I had reason to run this remotely (and transparently within a Makefile) +via ssh. I use the gmake rule:

+
%.bit : %.xnf
+    ssh -x -a -o 'BatchMode yes' ${ALLIANCE_HOST} \
+           remote_alliance ${REMOTE_DIR} $(basename $@) 2>&1 < $<
+scp ${ALLIANCE_HOST}:${REMOTE_DIR}/$@ .
+
+
+

and the remote_alliance script (on ${ALLIANCE_HOST}):

+
/bin/csh
+cd $1
+cat >! $2.xnf
+xnf2pcf <$2.xnf >! $2.pcf
+./backend $2
+
+
+

There is now a “Xilinx on Linux HOWTO” at http://www.polybus.com/xilinx_on_linux.html +I haven’t tried this yet, it looks interesting.

+
+
+

Downloading:

+

I use the XESS (http://www.xess.com/) XSP-10 development board, which +uses the PC parallel (printer) port for downloading and interaction +with the host. They made an old version of their download program +public domain, posted it at http://www.xess.com/FPGA/xstools.zip , +and now there is a Linux port at ftp://ftp.microux.com/pub/pilotscope/xstools.tar.gz .

+

The above hints are based on my experience with Foundation 1.5 on NT +(gack) and Alliance 2.1i on Solaris. Your mileage may vary. Good luck!

+
+
+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/tgt-vvp/tgt-vvp.html b/developer/guide/tgt-vvp/tgt-vvp.html new file mode 100644 index 0000000000..3dfde07c8f --- /dev/null +++ b/developer/guide/tgt-vvp/tgt-vvp.html @@ -0,0 +1,151 @@ + + + + + + + + + The VVP Target — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

The VVP Target

+
+

Symbol Name Conventions

+

There are some naming conventions that the vvp target uses for +generating symbol names.

+
    +
  • wires and regs

  • +
+

Nets and variables are named V_<full-name> where <full-name> is the +full hierarchical name of the signal.

+
    +
  • Logic devices

  • +
+

Logic devices (and, or, buf, bufz, etc.) are named L_<full_name>. In +this case the symbol is attached to a functor that is the output of +the logic device.

+
+
+

General Functor Web Structure

+

The net of gates, signals and resolvers is formed from the input +design. The basic structure is wrapped around the nexus, which is +represented by the ivl_nexus_t.

+

Each nexus represents a resolved value. The input of the nexus is fed +by a single driver. If the nexus in the design has multiple drivers, +the drivers are first fed into a resolver (or a tree of resolvers) to +form a single output that is the nexus.

+

The nexus, then, feeds its output to the inputs of other gates, or to +the .net objects in the design.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/vpi/index.html b/developer/guide/vpi/index.html new file mode 100644 index 0000000000..6a201c6cb2 --- /dev/null +++ b/developer/guide/vpi/index.html @@ -0,0 +1,129 @@ + + + + + + + + + VPI in Icarus Verilog — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

VPI in Icarus Verilog

+ +
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/vpi/va_math.html b/developer/guide/vpi/va_math.html new file mode 100644 index 0000000000..75c38761f9 --- /dev/null +++ b/developer/guide/vpi/va_math.html @@ -0,0 +1,216 @@ + + + + + + + + + Verilog-A math library — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Verilog-A math library

+
+

License.

+
+

Verilog-A math library built for Icarus Verilog +https://github.com/steveicarus/iverilog/

+

Copyright (C) 2007-2024 Cary R. (cygcary@yahoo.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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

+
+
+
+

Standard Verilog-A Mathematical Functions.

+

The va_math VPI module implements all the standard math functions provided +by Verilog-A as Verilog-D system functions. The names are the same except +like all Verilog-D system functions the name must be prefixed with a ‘$’. +For reference the functions are:

+
$ln(x)       --  Natural logarithm
+$log10(x)    --  Decimal logarithm
+$exp(x)      --  Exponential
+$sqrt(x)     --  Square root
+$min(x,y)    --  Minimum
+$max(x,y)    --  Maximum
+$abs(x)      --  Absolute value
+$floor(x)    --  Floor
+$ceil(x)     --  Ceiling
+$pow(x,y)    --  Power (x**y)
+$sin(x)      --  Sine
+$cos(x)      --  Cosine
+$tan(x)      --  Tangent
+$asin(x)     --  Arc-sine
+$acos(x)     --  Arc-cosine
+$atan(x)     --  Arc-tangent
+$atan2(y,x)  --  Arc-tangent of y/x
+$hypot(x,y)  --  Hypotenuse (sqrt(x**2 + y**2))
+$sinh(x)     --  Hyperbolic sine
+$cosh(x)     --  Hyperbolic cosine
+$tanh(x)     --  Hyperbolic tangent
+$asinh(x)    --  Arc-hyperbolic sine
+$acosh(x)    --  Arc-hyperbolic cosine
+$atanh(x)    --  Arc-hyperbolic tangent
+
+
+

The only limit placed on the x and y arguments by the library is that they +must be numbers (not constant strings). The underlying C library controls +any other limits placed on the arguments. Most libraries return +-Inf or +NaN for results that cannot be represented with real numbers. All functions +return a real result.

+
+
+

Standard Verilog-A Mathematical Constants.

+

The Verilog-A mathematical constants can be accessed by including the +“constants.vams” header file. It is located in the standard include +directory. Recent version of Icarus Verilog (0.9.devel) automatically +add this directory to the end of the list used to find include files. +For reference the mathematical constants are:

+
`M_PI        --  Pi
+`M_TWO_PI    --  2*Pi
+`M_PI_2      --  Pi/2
+`M_PI_4      --  Pi/4
+`M_1_PI      --  1/Pi
+`M_2_PI      --  2/Pi
+`M_2_SQRTPI  --  2/sqrt(Pi)
+`M_E         --  e
+`M_LOG2E     --  log base 2 of e
+`M_LOG10E    --  log base 10 of e
+`M_LN2       --  log base e of 2
+`M_LN10      --  log base e of 10
+`M_SQRT2     --  sqrt(2)
+`M_SQRT1_2   --  1/sqrt(2)
+
+
+
+
+

Using the Library.

+

Just add “-m va_math” to your iverilog command line/command file and +`include the “constants.vams” file as needed.

+
+
+

Thanks

+

I would like to thank Larry Doolittle for his suggestions and +Stephen Williams for developing Icarus Verilog.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/vpi/vpi.html b/developer/guide/vpi/vpi.html new file mode 100644 index 0000000000..2bf12abf3e --- /dev/null +++ b/developer/guide/vpi/vpi.html @@ -0,0 +1,166 @@ + + + + + + + + + VPI Modules in Icarus Verilog — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

VPI Modules in Icarus Verilog

+

The VPI interface for Icarus Verilog works by creating from a +collection of PLI applications a single vpi module. The vpi module +includes compiled code for the applications linked together (with any +other libraries that the applications need) into a module with two +exported symbols, the vpip_set_callback function and the +vlog_startup_routines array.

+

The product that wishes to invoke the module (normally at run time) loads +the module, locates and calls the vpip_set_callback function to pass the +the module a jump table that allows the module to access the VPI routines +implemented by the product, then locates the vlog_startup_routines table +and calls all the startup routines contained in that table. It is possible +for a product to link with many modules. In that case, all the modules are +linked in and startup routines are called in order.

+

The product that uses vpi modules uses the environment variable +VPI_MODULE_PATH as a ‘:’ separated list of directories. This is the +module search path. When a module is specified by name (using whatever +means the product supports) the module search path is scanned until +the module is located.

+

The special module names “system.vpi”, “v2005_math.vpi”, “v2009.vpi”, +and “va_math.vpi” are part of the core Icarus Verilog distribution and +include implementations of the standard system tasks/functions. The +additional special module names “vhdl_sys.vpi” and “vhdl_textio.vpi” +include implementations of private functions used to support VHDL.

+
+

Compiling A VPI Module

+

See the documentation under: Using VPI

+
+
+

Tracing VPI Use

+

The vvp command includes the ability to trace VPI calls. This is +useful if you are trying to debug a problem with your code. To +activate tracing simply set the VPI_TRACE environment variable, with +the path to a file where trace text gets written. For example:

+
setenv VPI_TRACE /tmp/foo.txt
+
+
+

This tracing is pretty verbose, so you don’t want to run like this +normally. Also, the format of the tracing messages will change +according to my needs (and whim) so don’t expect to be able to parse +it in software.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/vvp/debug.html b/developer/guide/vvp/debug.html new file mode 100644 index 0000000000..206858a4fd --- /dev/null +++ b/developer/guide/vvp/debug.html @@ -0,0 +1,140 @@ + + + + + + + + + Debug Aids For VVP — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Debug Aids For VVP

+

Debugging vvp can be fiendishly difficult, so there are some built in +debugging aids. These are enabled by setting the environment variable +VVP_DEBUG to the path to an output file. Then, various detailed debug +tools can be enabled as described below.

+
    +
  • .resolv

  • +
+

The .resolv can print debug information along with a label by +specifying the debug output label on the .resolv line:

+
.resolv tri$<label>
+
+
+

In this case, the “$” character directly after the “tri” enables debug +dumps for this node, and the <label> is the label to prepend to log +messages from this node.

+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/vvp/index.html b/developer/guide/vvp/index.html new file mode 100644 index 0000000000..b2fb669cc7 --- /dev/null +++ b/developer/guide/vvp/index.html @@ -0,0 +1,132 @@ + + + + + + + + + VVP - Verilog Virtual Processor — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/vvp/opcodes.html b/developer/guide/vvp/opcodes.html new file mode 100644 index 0000000000..28a62e766c --- /dev/null +++ b/developer/guide/vvp/opcodes.html @@ -0,0 +1,1390 @@ + + + + + + + + + Executable Instruction Opcodes — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Executable Instruction Opcodes

+

Instruction opcodes all start with a % character and have 0 or more +operands. In no case are there more than 3 operands. This chapter +describes the specific behavior of each opcode, in enough detail +(I hope) that its complete effect can be predicted.

+

General Principles of Arithmetic (current plan):

+

The binary arithmetic instruction in general takes three parameters, +the left operand, the right operand, and the base. The left operand is +replaced with the result, which is the same width as the left and +right operands.

+

General Principles of Arithmetic (new plan):

+

For strings, all arithmetic is stack based. That is, there is an +abstract stack of strings from which operations pull their operands +and push their results. This is somewhat like FORTH (or an HP calculator +RPN notation) and spares the need to keep register addresses in +operands. I may find this leads to a more compact form of instruction +code, and may lead to more efficient operators overall, and in +particular I may find improved efficiency overall; so after the +experience of implementing it for strings, I’ll want to change other +types around to using this method as well. Keep this in mind whenever +considering adding new instructions to vvp.

+
+

Flags

+

There are up to 16 bits in each thread that are available for +flags. These are used as destinations for operations that return +boolean values, for example comparisons. They are also used as inputs +for test and branch opcodes.

+
    +
  • %abs/wr

  • +
+

This instruction calculates the absolute value of a real value. It uses +the fabs() function in the run-time to do the work, and manipulates +the top of the real-value stack.

+
    +
  • %add

  • +
  • %addi <vala>, <valb>, <wid>

  • +
+

This opcode pops and adds two vec4 values from the vec4 stack, adds +them, and pushes the result back to the stack. The input values must +have the same size, and the pushed result will have the same width.

+

The %addi variant takes one operand from the stack, the other is an +immediate value (See %pushi/vec4).

+

See also the %sub instruction.

+
    +
  • %add/wr

  • +
+

This is the real valued version of the %add instruction. The arguments +are popped from the stack, right operand then left, and the result +pushed in place

+

See also the %sub/wr instruction.

+
    +
  • %alloc <scope-label>

  • +
+

This instruction allocates the storage for a new instance of an +automatically allocated scope.

+
    +
  • %and

  • +
+

Perform the bitwise AND of the two vectors popped from the vec4 stack, +and push the result. Each bit is calculated independent of other +bits. AND means the following:

+
+

0 and ? –> 0 +? and 0 –> 0 +1 and 1 –> 1 +otherwise x

+
+

The input vectors must be the same width, and the output vector will +be the width of the input.

+
    +
  • %and/r

  • +
+

Pop the top value from the vec4 stack, perform a reduction &, then +return the single-bit result.

+
    +
  • %assign/ar <array-label>, <delay>

  • +
  • %assign/ar/d <array-label>, <delayx>

  • +
  • %assign/ar/e <array-label>

  • +
+

The %assign/ar instruction assigns a real value to a word in the +labeled real array. The <delay> is the delay in simulation time to +the assignment (0 for non-blocking assignment) and the value is popped +from the real value stack.

+

The memory word address is read from index register 3. The address is +in canonical form.

+

The %assign/ar/d variation reads the delay from an integer register that +is given by the <delayx> value. This should not be 3 or the <bit> index, +of course, since these registers contain the word address and the value.

+

The %assign/ar/e variation uses the information in the thread +event control registers to determine when to perform the assign. +%evctl is used to set the event control information.

+
    +
  • %assign/v0 <var-label>, <delay>, <bit> (XXXX Old description)

  • +
  • %assign/v0/d <var-label>, <delayx>, <bit> (XXXX Old description)

  • +
  • %assign/v0/e <var-label>, <bit> (XXXX Old description)

  • +
+

The %assign/v0 instruction is a vector version of non-blocking +assignment. The <delay> is the number of clock ticks in the future +where the assignment should be schedule, and the <bit> is the base of +the vector to be assigned to the destination. The vector width is in +index register 0.

+

The %assign/v0/d variation gets the delay instead from an integer +register that is given by the <delayx> value. This should not be 0, of +course, because integer 0 is taken with the vector width.

+

The %assign/v0/e variation uses the information in the thread +event control registers to determine when to perform the assign. +%evctl is used to set the event control information.

+

The <var-label> references a .var object that can receive non-blocking +assignments. For blocking assignments, see %set/v.

+
    +
  • %assign/vec4 <var-label>, <delay>

  • +
  • %assign/vec4/d <var-label>, <delayx>

  • +
  • %assign/vec4/e <var-label>

  • +
+

The %assign/vec4 instruction is a vec4 version of non-blocking +assignment. The <delay> is the number of clock ticks in the future +where the assignment should schedule, and the value to assign is +pulled from the vec4 stack.

+

The %assign/vec4/d instruction is the same, but gets its delay value +from the index register <delayx> instead.

+
    +
  • %assign/vec4/a/d <var-label>, <off-index>, <delay-index>

  • +
  • %assign/vec4/a/e <var-label>, <off-index>

  • +
+

This instruction implements delayed assignment to an array word. The +value is popped from the vec4 stack; the width is taken from the +popped value. The <off-index> index register contains the canonical +offset into the memory word for a part select, and the <delay-index> +index register contains the delay for the assignment. Index register 3 +contains the word address.

+

The <off-index> and <delay-index> index registers can be 0, which +means a zero value instead of the contents of index register 0.

+

If flag bit 4 is set, then the value will be popped from the stack, +but it will not be assigned. This handles the case that the index +values is undefined.

+
    +
  • %assign/vec4/off/d <var-label>, <off-index>, <delay-index>

  • +
+

This is for writing parts to the target variable. The <var-label> is +the variable to write, as usual. The <off-index> selects an index +register that holds the offset into the target variable, and the +<delay-index> selects the index register that contains the delay. The +offset is in canonical bits. The width that is written is taken from +the width of the value on the stack.

+

The actual assignment is suppressed if flags-4 is 1. This is so that +calculations of offset can set the flag on errors.

+
    +
  • %assign/wr <vpi-label>, <delay>

  • +
  • %assign/wr/d <vpi-label>, <delayx>

  • +
  • %assign/wr/e <vpi-label>

  • +
+

This instruction provides a non-blocking assign of the real value +given in <index> to the real object addressed by the <vpi-label> +label after the given <delay>. The real value is popped from the stack.

+

The %assign/wr/d variation gets the delay from integer register +<delayx>.

+

The %assign/wr/e variation uses the information in the thread +event control registers to determine when to perform the assign. +%evctl is used to set the event control information.

+
    +
  • %blend

  • +
+

This instruction blends the bits of two vectors into a result in a +manner line the expressions (‘bx ? <a> : <b>). The two source vectors +are popped from the vec4 stack (and must have the same width) and the +result pushed in their place. The truth table for each bit is:

+
+

1 1 –> 1 +0 0 –> 0 +z z –> z +x x –> x +…. –> x

+
+

In other words, if the bits are identical, then take that +value. Otherwise, the value is x.

+
    +
  • %blend/wr

  • +
+

This instruction blends real values for the ternary operator. If the +values match return that otherwise return 0.0. Two values are popped +from the stack, one is pushed back.

+
    +
  • %breakpoint

  • +
+

This instruction unconditionally breaks the simulator into the +interactive debugger. The idea is to stop the simulator here and give +the user a chance to display the state of the simulation using +debugger commands.

+

This may not work on all platforms. If run-time debugging is compiled +out, then this function is a no-op.

+
    +
  • %callf/obj <code-label>, <scope-label>

  • +
  • %callf/real <code-label>, <scope-label>

  • +
  • %callf/str <code-label>, <scope-label>

  • +
  • %callf/vec4 <code-label>, <scope-label>

  • +
  • %callf/void <code-label>, <scope-label>

  • +
+

More directly implement function calling. This subsumes the %fork and +%join of the more general task and block calling, but is optimized for +functions, which are threads of a special, constrained sort.

+

The different variants reflect the different return types for the +called function. For example, if the function returns a string, the +%callf/str opcode is used, and will push the string return value into +the caller’s string stack. The %callf/void function is special in that +is pushes no value onto any stack.

+
    +
  • %cassign/vec4 <var-label>

  • +
  • %cassign/vec4/off <var-label>, <off-index>

  • +
+

Perform a continuous assign of a constant value to the target +variable. This is similar to %set, but it uses the cassign port +(port-1) of the signal functor instead of the normal assign, so the +signal responds differently. See “VARIABLE STATEMENTS” in the +README.txt file.

+

The %cassign/vec4/off instruction will check the flags[4] flag, and if +it is 1, it will suppress the assignment. This is so that failed index +calculations can report the failure by setting the flag.

+
    +
  • %cassign/wr <var-label>

  • +
+

Perform a continuous assign of a constant real value to the target +variable. See %cassign/v above. The value is popped from the real +value stack.

+
    +
  • %cast2

  • +
+

Pop a value from the vec4 stack, convert it using Verilog rules to a +vector2 (binary) value, and push the result.

+
    +
  • %cast/vec2/dar <wid>

  • +
+

Pop a dynamic array value from the object stack, convert it to a 2-state +vector that is <wid> bits wide, and push the result to the vec4 stack. +If the dynamic array does not fit exactly in <wid> bits, print an error +message and stop the simulation.

+
    +
  • %cast/vec4/dar <wid>

  • +
+

Pop a dynamic array value from the object stack, convert it to a 4-state +vector that is <wid> bits wide, and push the result to the vec4 stack. +If the dynamic array does not fit exactly in <wid> bits, print an error +message and stop the simulation.

+
    +
  • %cast/vec4/str <wid>

  • +
+

Pop a value from the string stack, convert it to a vector that is <wid> +bits wide, and push the result to the vec4 stack. If the string does not +fit exactly in <wid> bits, print an error message and stop the simulation.

+
    +
  • %cmp/s

  • +
  • %cmp/u

  • +
  • %cmp/e

  • +
  • %cmp/ne

  • +
  • %cmpi/s <vala>, <valb>, <wid>

  • +
  • %cmpi/u <vala>, <valb>, <wid>

  • +
  • %cmpi/e <vala>, <valb>, <wid>

  • +
  • %cmpi/ne <vala>, <valb>, <wid>

  • +
+

These instructions perform a generic comparison of two vectors of +equal size. Two values are pulled from the top of the stack, and not +replaced. The results are written into flag bits 4,5,6. The +expressions (a<b), (a==b) and (a===b) are calculated, with (b) popped +from the stack first, then (a).

+

The results of the comparison go into flags 4, 5, 6 and 7:

+
+

4: eq (equal) +5: lt (less than) +6: eeq (case equal)

+
+

The eeq bit is set to 1 if all the bits in the vectors are exactly the +same, or 0 otherwise. The eq bit is true if the values are logically +the same. That is, x and z are considered equal. In other words the eq +bit is the same as == and the eeq bit ===.

+

The lt bit is 1 if the left vector is less than the right vector, or 0 +if greater than or equal to the right vector. It is the equivalent of +the Verilog < operator. Combinations of these three bits can be used +to implement all the Verilog comparison operators.

+

The %cmp/u and %cmp/s differ only in the handling of the lt bit. The +%cmp/u does an unsigned compare, whereas the %cmp/s does a signed +compare. In either case, if either operand contains x or z, then lt +bit gets the x value.

+

The %cmp/e and %cmpi/e variants are the same, but they do not bother +to calculate the lt flag. These are faster if the lt flag is not needed.

+

The %cmp/ne and %cmpi/ne variants are the same as the %cmp/e and +%cmpi/e variants, but the 4 and 6 flags are inverted in order to +eliminate the need for a %flag_inv instruction to implement != and !== +operations.

+
    +
  • %cmp/we

  • +
  • %cmp/wne

  • +
+

These instructions perform a wild comparison of two vectors of equal +size. Two values are pulled from the top of the stack, and not replaced. +The results are written into flag bit 4. The comparisons work like eq/ne +except an x/z bit in the r-value will match any l-value bit.

+

The %cmp/wne variant is the same as %cmp/we, but the 4 flag is inverted +in order to eliminate the need for a %flag_inv instruction to implement +the !=? operator.

+
    +
  • %cmp/wr

  • +
+

Compare real values for equality and less-then. This opcode pops to +values from the real-value stack and writes the comparison result to +bits 4/5. The expressions (a < b) and (a==b) are calculated, with (b) +popped from the stack first, then (a).

+
    +
  • %cmp/z

  • +
  • %cmp/x

  • +
+

These instructions are for implementing the casez and casex +comparisons. These work similar to the %cmp/u instructions, except +only an eq bit is calculated. These comparisons both treat z values in +the left or right operand as don’t care positions. The %cmp/x +instruction will also treat x values in either operand as don’t care.

+

Only bit 4 is set by these instructions.

+
    +
  • %cmp/str

  • +
+

This instruction pops the top two strings from the string stack and +compares them. The results of the comparison go into bits 4 and 5:

+
+

4: eq (equal) +5: lt (less than)

+
+

For the purposes of calculating the lt bit, the top string is the +right operand and the string underneath is the left operand. This +instruction removes two strings from the stack.

+
    +
  • %concat/str

  • +
  • %concati/str <string>

  • +
+

Pop the top string, and concatenate it to the new top string. Or think +of it as passing the tail, then the head, concatenating them, and +pushing the result. The stack starts with two strings in the stack, +and ends with one string in the stack.

+

The %concati/str form pops only one value from the stack. The right +part comes from the immediate value.

+
    +
  • %concat/vec4

  • +
  • %concati/vec4 <vala>, <valb>, <wid>

  • +
+

Pop two vec4 vectors, concatenate them, and push the combined +result. The top of the vec4 stack is the LSB of the result, and the +next in this stack is the MSB bits of the result.

+

The %concati/vec4 form takes an immediate value and appends it (lsb) +to the value on the top of the stack. See the %pushi/vec4 instruction +for how to describe the immediate value.

+
    +
  • %cvt/sr <index>

  • +
  • %cvt/ur <bit-l>

  • +
+

Pop a word from the real-value stack, convert it to a signed or +unsigned integer, and write it to the <index> index +register. Precision may be lost in the conversion.

+
    +
  • %cvt/rv

  • +
  • %cvt/rv/s

  • +
+

The %cvt/rv instruction pops a value from the thread vec4 stack and +converts it to a real word. Push the result onto the real value +stack. Precision may be lost in the conversion.

+

The %cvt/rv/s instruction is the same as %cvt/rv, but treats the thread +vector as a signed value.

+
    +
  • %cvt/vr <wid>

  • +
+

The %cvt/vr opcode converts a real word from the stack to a vec4 that +is <wid> wide. Non-integer precision is lost in the conversion, and +the real value is popped from the stack. The result is pushed to the +vec4 stack.

+
    +
  • %deassign <var-label>, <base>, <width>

  • +
+

Deactivate and disconnect a procedural continuous assignment to a +variable. The <var-label> identifies the affected variable.

+

The <base> and <width> are used to determine what part of the signal +will be deactivated. For a full deactivation the <base> is 0 and +<width> is the entire signal width.

+
    +
  • %deassign/wr <var-label>

  • +
+

The same as %deassign above except this is used for real variables.

+
    +
  • %debug/thr

  • +
+

These opcodes are aids for debugging the vvp engine. The vvp code +generator should not generate these, and they should not alter code +flow, data contents, etc.

+
    +
  • %delay <low>, <high>

  • +
+

This opcode pauses the thread, and causes it to be rescheduled for a +time in the future. The amount is the number of the ticks in the +future to reschedule, and is >= 0. If the %delay is zero, then the +thread yields the processor for another thread, but will be resumed in +the current time step.

+

The delay amount is given as 2 32bit numbers, so that 64bit times may +be represented.

+
    +
  • %delayx <idx>

  • +
+

This is similar to the %delay opcode, except that the parameter +selects an index register, which contains the actual delay. This +supports run-time calculated delays.

+
    +
  • %delete/obj <var-label>

  • +
+

Arrange for the dynamic object at the target label to be deleted. +This has no effect on the object or string stack. Note that this is +the same as:

+
+

%null ; +%store/obj <var-label>

+
+

but that idiom is expected to be common enough that it warrants an +optimized shorthand.

+
    +
  • %disable <scope-label>

  • +
+

This instruction terminates threads that are part of a specific +scope. The label identifies the scope in question, and the threads are +the threads that are currently within that scope.

+
    +
  • %disable/flow <scope-label>

  • +
+

This instruction is similar to %disable except that it will only disable a +single thread of the specified scope. The disabled thread will be the thread +closest to the current thread in the thread hierarchy. This can either be thread +itself or one of its parents.

+

It is used to implement flow control statements called from within a thread that +only affect the thread or its parents. E.g. SystemVerilog return, continue +or break.

+
    +
  • %disable/fork

  • +
+

This instruction terminates all the detached children for the current +thread. There should not be any non-detached children.

+
    +
  • %div <bit-l>, <bit-r>, <wid>

  • +
  • %div/s <bit-l>, <bit-r>, <wid>

  • +
+

This instruction arithmetically divides the <bit-l> vector by the +<bit-r> vector, and leaves the result in the <bit-l> vector. IF any of +the bits in either vector are x or z, the entire result is x.

+

The %div/s instruction is the same as %div, but does signed division.

+
    +
  • %div/wr

  • +
+

This opcode divides the left operand by the right operand. If the +right operand is 0, then the result is NaN.

+
    +
  • %dup/real

  • +
  • %dup/vec4

  • +
  • %dup/obj

  • +
+

These opcodes duplicate the value on the top of the stack for the +corresponding type.

+
    +
  • %evctl <functor-label> <idx>

  • +
  • %evctl/c

  • +
  • %evctl/s <functor-label> <idx>

  • +
  • %evctl/i <functor-label> <value>

  • +
+

These instructions are used to put event and repetition information +into the thread event control registers. These values are then used +by the %assign/e instructions to do not blocking event control. The +<functor-label> is the event to trigger on and the <idx> is an index +register to read the repetition count from (signed or unsigned). +%evctl/i sets the repetition to an immediate unsigned value.

+

%evctl/c clears the event control information. This is needed if a +%assign/e may be skipped since the %assign/e statements clear the +event control information and the other %evctl statements assert +that this information has been cleared. You can get an assert if +this information is not managed correctly.

+
    +
  • %event <functor-label>

  • +
  • %event/nb <functor-label>

  • +
+

This instruction is used to send a pulse to an event object. The +<functor-label> is an event variable. This instruction simply writes +an arbitrary value to the event to trigger the event.

+
    +
  • %file_line <file> <line> <description>

  • +
+

This command emits the provided file and line information along with +the description when it is executed. The output is sent to stderr and +the format of the output is:

+
+

<file>:<line>: <description>

+
+

<file> is the unsigned numeric file index. +<line> is the unsigned line number. +<description> is a string, if string is 0 then the following default +message is used: “Procedural tracing.”.

+
    +
  • %flag_inv <flag>

  • +
+

This instruct inverts a flag bit.

+
    +
  • %flag_mov <flag1>, <flag2>

  • +
+

This instruction copies the flag bit from <flag2> to <flag1>.

+
    +
  • %flag_or <flag1>, <flag2>

  • +
+

This instruction calculates the Verilog OR of the flag bits in <flag1> +and <flag2>, and leaves the result in <flag1>.

+
    +
  • %flag_set/imm <flag>, <value>

  • +
+

This instruction sets an immediate value into a flag bit. This is a +single bit, and the value is 0==0, 1==1, 2==z, 3==x.

+
    +
  • %flag_get/vec4 <flag>

  • +
  • %flag_set/vec4 <flag>

  • +
+

These instructions provide a means for accessing flag bits. The +%flag_get/vec4 loads the numbered flag as a vec4 on top of the vec4 +stack, and the %flag_set/vec4 pops the top of the vec4 stack and +writes the LSB to the selected flag.

+
    +
  • %force/vec4 <label>

  • +
  • %force/vec4/off <label>, <off>

  • +
  • %force/vec4/off/d <label>, <off>, <delay>

  • +
+

Perform a “force” assign of a values to the target variable. The value +to be forced is popped from the vec4 stack and forced to the target +variable. The /off variant forces a part of a vector. The width of the +part comes from the width of the popped value, and the <off> is an +index register that contains the canonical offset where the value +gets written. The <delay> is an index register that contains the +delay.

+

The %force/vec4/off instructions will test the value of flags[4], and if +it is 1, will suppress the actual assignment. This is intended to help +with detection of invalid index expressions.

+
    +
  • %force/wr <var-label>

  • +
+

Force a constant real value to the target variable. See %force/v +above. The value is popped from the real value stack.

+
    +
  • %fork <code-label>, <scope-label>

  • +
+

This instruction is similar to %jmp, except that it creates a new +thread to start executing at the specified address. The new thread is +created and pushed onto the child stack. It is also marked runnable, +but is not necessarily started until the current thread yields.

+

The %fork instruction has no effect other than to push a child thread.

+

See also %join.

+
    +
  • %free <scope-label>

  • +
+

This instruction de-allocates the storage for a previously allocated +instance of as automatically allocated scope.

+
    +
  • %inv

  • +
+

Perform a bitwise invert of the vector on top of the vec4 stack. The result +replaces the input. Invert means the following, independently, for each +bit:

+
+

0 –> 1 +1 –> 0 +x –> x +z –> x

+
+
    +
  • %ix/vec4 <idx>

  • +
  • %ix/vec4/s <idx>

  • +
+

This instruction loads a vec4 value from the vec4 stack, into the +index register <idx>. The value is popped from the vec4 stack and +written to the index register.

+

The %ix/vec4 instruction converts the 4-value bits into a binary +number, without sign extension. If any of the bits of the vector is x +or z, then the index register gets the value 0. The %ix/vec4/s +instruction is the same, except that it assumes the source vector is +sign extended to fit the index register.

+

The instruction also writes into flag 4 a 1 if any of the bits of the +input vector are x or z. This is a flag that the 0 value written into +the index register is really the result of calculating from unknown +bits. It writes an X into flag 4 if the vec4 value overflows the index +register.

+
+

4: unknown value or overflow +5: (reserved) +6: (reserved)

+
+
    +
  • %ix/getv <idx>, <functor-label>

  • +
  • %ix/getv/s <idx>, <functor-label>

  • +
+

These instructions are like the %ix/vec4 instructions, except that they +read directly from a functor label instead of from thread bits. They set +flag 4 just like %ix/get (overflow is not currently checked by ix/getv/s).

+
    +
  • %ix/load <idx>, <low>, <high>

  • +
+

This instruction loads an immediate value into the addressed index +register. The index register holds 64 bit numeric values, so <low> +and <high> are used to separate the value in two 32 bit chunks. +The idx value selects the index register. This is different from +%ix/get, which loads the index register from a value in the thread bit +vector. The values are unsigned decimal values and are combined as +<high> << 32 | <low> to produce the final value.

+
    +
  • %ix/add <idx>, <low>, <high>

  • +
  • %ix/sub <idx>, <low>, <high>

  • +
  • %ix/mul <idx>, <low>, <high>

  • +
+

These instructions add, subtract, or multiply the selected index +register by the immediate value. The 64 bit immediate value is built +from the two 32 bit chunks <low> and <high> (see %ix/load above). +The <idx> value selects the index register.

+
    +
  • %ix/mov <dst>, <src>

  • +
+

This instruction simply sets the index register <dst> to the value of +the index register <src>.

+
    +
  • %jmp <code-label>

  • +
+

The %jmp instruction performs an unconditional branch to a given +location. The parameter is the label of the destination instruction.

+
    +
  • %jmp/[01xz] <code-label>, <flag>

  • +
+

This is a conditional version of the %jmp instruction. In this case, +a flag bit (addressed by <bit>) is tested. If it is one of the +values in the part after the /, the jump is taken. For example:

+
+

%jmp/xz T_label, 8;

+
+

will jump to T_label if bit 8 is x or z.

+
    +
  • %join

  • +
+

This is the partner to %fork. This instruction causes the thread to +wait for the top thread in the child stack to terminate, then +continues. It has no effect in the current thread other than to wait +until the top child is cleared.

+

It is an error to execute %join if there are no children in the child +stack. Every %join in the thread must have a matching %fork that +spawned off a child thread.

+

If the matching child instruction is still running, a %join suspends +the calling thread until the child ends. If the child is already +ended, then the %join does not block or yield the thread.

+
    +
  • %join/detach <n>

  • +
+

This is also a partner to %fork. This instruction causes the thread +to detach <n> threads from the current thread. The <n> should be ALL +the children, and none of those children may be automatic. This +instruction is used to implement join_none and join_any from the +Verilog source.

+
    +
  • %load/obj <var-label>

  • +
+

This instruction loads an object handle and pushes it to the top of +the object handle stack.

+

See also %store/obj.

+
    +
  • %load/real <vpi-label>

  • +
  • %load/dar/r <functor-label>

  • +
+

The %load/real instruction reads a real value from the vpi-like object +and pushes it to the top of the real value stack.

+

The %load/dar/r loads the real word from the darray and pushes it onto +the stack.

+
    +
  • %load/str <var-label>

  • +
  • %load/stra <array-label>, <index>

  • +
  • %load/dar/str <var-label>

  • +
+

The %load/str instruction gets the string from the string variable and +pushes in to the string stack. (See also %store/str)

+

The %load/dar/str is similar, but the variable is a dynamic array of +strings, and there is an index value in index register 3. +(See also %store/dar/str)

+
    +
  • %load/v <bit>, <functor-label>, <wid> (XXXX Old implementation)

  • +
+

This instruction loads a vector value from the given functor node into +the specified thread register bit. The functor-label can refer to a +.net, a .var or a .functor with a vector output. The entire vector, +from the least significant up to <wid> bits, is loaded starting at +thread bit <bit>. It is an OK for the width to not match the vector +width at the functor. If the <wid> is less than the width at the +functor, then the most significant bits are dropped. If the <wid> is +more than the width at the functor, the value is padded with X bits.

+
    +
  • %load/vec4 <var-label>

  • +
+

This instruction loads a vector value from the given functor node and +pushes it onto the vec4 stack. See also the %store/vec4 instruction.

+
    +
  • %load/vec4a <arr-label>, <addr-index>

  • +
+

This instruction loads a vec4 value from the array and pushes the +value onto the stack. The <addr-index> is the index register that +holds the canonical array index.

+

The load checks flag bit 4. If it is 1, then the load it cancelled and +replaced with a load of all X bits. See %ix/vec4.

+
    +
  • %load/ar <array-label>, <index>

  • +
+

The %load/ar instruction reads a real value from an array. The <index> +is the index register that contains the canonical word address into +the array.

+
    +
  • %loadi/wr <bit>, <mant>, <exp>

  • +
+

This opcode loads an immediate value, floating point, into the word +register selected by <bit>. The mantissa is an unsigned integer value, +up to 32 bits, that multiplied by 2**(<exp>-0x1000) to make a real +value. The sign bit is OR-ed into the <exp> value at bit 0x4000, and +is removed from the <exp> before calculating the real value.

+

If <exp>==0x3fff and <mant> == 0, the value is +inf. +If <exp>==0x7fff and <mant> == 0, the value is -inf. +If <exp>==0x3fff and <mant> != 0, the value is NaN.

+
    +
  • %max/wr

  • +
  • %min/wr

  • +
+

This instruction pops the top two values from the real stack and +pushes back the max(min) value. Avoid returning NaN by selecting the +other if either is NaN.

+
    +
  • %mod

  • +
  • %mod/s

  • +
+

This instruction calculates the modulus %r of the left operand, and +replaces the left operand with the result. The left and right vectors +are popped from the vec4 stack and have identical width. The result is +pushed onto the vec4 stack.

+

The /s form does signed %.

+
    +
  • %mod/wr

  • +
+

This opcode is the real-valued modulus of the two real values.

+
    +
  • %mul

  • +
  • %muli <vala>, <valb>, <wid>

  • +
+

This instruction multiplies the left vector by the right vector, the +vectors pare popped from the vec4 stack and have the same width. If +any of the bits of either vector are x or z, the result is +x. Otherwise, the result is the arithmetic product. In any case, the +result is pushed back on the vec4 stack.

+
    +
  • %mul/wr

  • +
+

This opcode multiplies two real words together.

+
    +
  • %nand

  • +
+

Perform the bitwise NAND of two vec4 vectors, and push the result. Each +bit is calculated independent of other bits. NAND means the following:

+
+

0 and ? –> 1 +? and 0 –> 1 +1 and 1 –> 0 +otherwise x

+
+
    +
  • %new/cobj <label>

  • +
+

Create a new class object. The <label> is the VPI label for a class +type definition.

+
    +
  • %new/darray <idx>, “<type>”

  • +
+

Create a new array (of int objects) with a size. the <idx> is the +address of an index variable that contains the computed array size to +use. The <type> is a string that expresses the type of the elements of +the array. See also %delete/obj

+

The supported types are:

+
+

“b<N>” - unsigned bool <N>-bits +“sb<N>” - signed bool <N>-bits +“r” - real +“S” - SystemVerilog string

+
+
    +
  • %nor

  • +
+

Perform the bitwise nor of vec4 vectors, and push the result. Each bit +in the source vectors is combined to make a result bit according to the +truth table.

+
+

1 nor ? –> 0 +? nor 1 –> 0 +0 nor 0 –> 1 +otherwise x

+
+
    +
  • %nor/r <dst>, <src>, <wid> (XXXX Old definition)

  • +
+

The %nor/r instruction is a reduction nor. That is, the <src> is a +vector with width, but the result is a single bit. The <src> vector is +not affected by the operation unless the <dst> bit is within the +vector. The result is calculated before the <dst> bit is written, so +it is valid to place the <dst> within the <src>.

+

The actual operation performed is the inverted or of all the bits in +the vector.

+
    +
  • %nor/r

  • +
+

The %nor/r instruction is a reduction nor. That is, a vec4 value is +popped from the vec4 stack, the bits of the vector are or’ed together +to a signal bit, that bit is inverted and the resulting 1-bit vector +pushed back to the vec4 stack. See also the “%or” instruction.

+
    +
  • %null

  • +
+

Push a null object and push it to the object stack. The null object +can be used with any class or darray object, so it is not typed.

+
    +
  • %or

  • +
+

Perform the bitwise or of two vectors. Pop two values from the vec4 +stack to get the input arguments. Each bit in the result is combined +with the corresponding bit in the input arguments, according to the +truth table:

+
+

1 or ? –> 1 +? or 1 –> 1 +0 or 0 –> 0 +otherwise x

+
+

The results is then pushed onto the vec4 stack. The inputs and the +output are all the same width.

+
    +
  • %or/r

  • +
+

This is a reduction version of the %or opcode. Pop a single value from +the vec4 stack, perform the reduction or and return the result to the stack.

+
    +
  • %pad <dst>, <src>, <wid> (XXXX Old version)

  • +
+

This instruction replicates a single bit in register space into a +destination vector in register space. The destination may overlap +the source bit. The <dst> may not be 0-3. This is useful for zero +or sign extending a vector.

+
    +
  • %pad/s <wid>

  • +
  • %pad/u <wid>

  • +
+

These instruction change the size of the top item in the vec4 +stack. If this item is larger then this, it is truncated. If smaller, +then extended. The /s variant sign extends, the /u variant unsigned +extends.

+
    +
  • %part/s <wid>

  • +
  • %part/u <wid>

  • +
+

This instruction implements a part select. It pops from the top of the +vec4 the base value, then it pops the base to select from. The width +is the fixed number <wid>. The result is pushed back to the stack.

+
    +
  • %pop/str <num>

  • +
  • %pop/real <num>

  • +
  • %pop/obj <num>, <skip>

  • +
  • %pop/vec4 <num>

  • +
+

Pop <num> items from the string/real/object/vec4 stack. This is the +opposite of the %pushX/str opcode which pushes a string to the +stack. The %pop/str is not normally needed because the %store/str +includes an implicit pop, but sometimes it is necessary to pop +explicitly.

+

The <skip> is the number of top positions on the stack to keep, +before starting to pop. This allows for popping positions other than +the top of the stack.

+
    +
  • %pow

  • +
  • %pow/s

  • +
+

The %pow opcode pops the “B” value from the stack, then pops the “A” +value from the stack, then pushes A**B back onto the stack. Of there +are any X or Z bits in A or B, then an X value is pushed onto the +stack instead of a calculated values.

+

The %pow/s opcode does the same for signed values.

+
    +
  • %pow/wr

  • +
+

This opcode raises the left operand by the right operand, and pushes +the result.

+
    +
  • %prop/v <pid>

  • +
  • %prop/obj <pid>, <idx>

  • +
  • %prop/r <pid>

  • +
  • %prop/str <pid>

  • +
+

Read a vector (/v) or real value (/r) or string (/str) or object from +the property number <pid> of the class object on the top of the +object stack. Push the resulting value to the appropriate stack. The +class object that is the source is NOT popped from the object stack.

+

The <idx> is the address of an index variable that selects the word of +an arrayed property. If the <idx> value is 0, then use index value +zero instead of reading index register zero. Use this form for +non-arrayed properties.

+
    +
  • %pushi/real <mant>, <exp>

  • +
+

This opcode loads an immediate value, floating point, into the real +value stack. The mantissa is an unsigned integer value, up to 32 bits, +that multiplied by 2**(<exp>-0x1000) to make a real value. The sign +bit is OR-ed into the <exp> value at bit 0x4000, and is removed from +the <exp> before calculating the real value.

+

If <exp>==0x3fff and <mant> == 0, the value is +inf. +If <exp>==0x7fff and <mant> == 0, the value is -inf. +If <exp>==0x3fff and <mant> != 0, the value is NaN.

+
    +
  • %pushi/str <text>

  • +
+

Push a literal string to the string stack.

+
    +
  • %pushi/vec4 <vala>, <valb>, <wid>

  • +
+

This opcode loads an immediate value, vector4, into the vector +stack. The <vala> is the boolean value bits, and the <valb> bits are +modifiers to support z and x values. The a/b encodings for the 4 +possible logic values are:

+
+

a b val +0 0 0 +1 0 1 +1 1 x +0 1 z

+
+

This opcode is limited to 32bit numbers.

+
    +
  • %pushv/str

  • +
+

Convert a vector to a string and push the string to the string +stack. The single argument is popped from the vec4 stack and the +result pushed to the string stack.

+
    +
  • %putc/str/v <functor-label>, <muxr>

  • +
+

Pop a vector byte from the thread vec4 stack and write it to a +character of the string variable at <functor-label>. This is +basically an implementation of <string>.putc(<muxr>, <val>) where +<val> is the 8bit vector popped from the stack.

+
    +
  • %qpop/b/real <functor-label>

  • +
  • %qpop/f/real <functor-label>

  • +
  • %qpop/b/str <functor-label>

  • +
  • %qpop/f/str <functor-label>

  • +
  • %qpop/b/v <functor-label>

  • +
  • %qpop/f/v <functor-label>

  • +
+

Pop values from a dynamic queue object.

+
    +
  • %release/net <functor-label>, <base>, <width>

  • +
  • %release/reg <functor-label>, <base>, <width>

  • +
+

Release the force on the signal that is represented by the functor +<functor-label>. The force was previously activated with a %force/v +statement. If no force was active on this functor the statement does +nothing. The %release/net sends to the labeled functor the release +command with net semantics: the unforced value is propagated to the +output of the signal after the release is complete. The %release/reg +sends the release command with reg semantics: the signal holds its +forced value until another value propagates through.

+

The <base> and <width> are used to determine what part of the signal +will be released. For a full release the <base> is 0 and <width> is +the entire signal width.

+
    +
  • %release/wr <functor-label>, <type>

  • +
+

Release the force on the real signal that is represented by the functor +<functor-label>. The force was previously activated with a %force/wr +statement. The <type> is 0 for nets and 1 for registers. See the other +%release commands above.

+
    +
  • %replicate <count>

  • +
+

Pop the vec4 value, replicate it <count> times, then push the +result. In other words, push the concatenation of <count> copies. +See also the %concat instruction.

+
    +
  • %ret/obj <index>

  • +
  • %ret/real <index>

  • +
  • %ret/str <index>

  • +
  • %ret/vec4 <index>, <offset>, <wid>

  • +
+

Write a value to the indexed function argument. The value is popped +from the appropriate stack and written into the argument. The return +value of a function is the first argument of the appropriate type, so +for example to store the return value for a real function, use +“%ret/real 0;”. It is up to the function caller to set up the argument +references.

+

The %ret/vec4 opcode works very much like the %store/vec4 opcode. The +<off> and <wid> operands are the offset and width of the subvector of +the destination value that is written by the value popped from the +vec4 stack. Off the <offset> is zero, then the literal offset is +zero. If the <offset> is non-zero, then it selects an index register +that contains the actual offset. In this case, flag-4 is tested, and +if not 1, the assign is suppressed.

+
    +
  • %retload/vec4 <index>

  • +
  • %retload/real <index>

  • +
  • %retload/str <index>

  • +
+

Read a value from the indexed function argument. The value is read +from the argument and pushed to the appropriate stack.

+
    +
  • %set/dar/obj/real <index>

  • +
  • %set/dar/obj/str <index>

  • +
  • %set/dar/obj/vec4 <index>

  • +
+

The “%set/dar/obj/real” opcode sets the top value from the real-value +stack to the index. This does NOT pop the real value off the +stack. The intent is that this value may be written to a bunch of +values.

+

The “%set/dar/obj/str” opcode does the same but for string values and +uses the string stack, and the “%set/dar/obj/vec4” for vec4 values and +the vector stack.

+
    +
  • %set/v <var-label>, <bit>, <wid> (XXXX Old definition)

  • +
+

This sets a vector to a variable, and is used to implement blocking +assignments. The <var-label> identifies the variable to receive the +new value. Once the set completes, the value is immediately available +to be read out of the variable. The <bit> is the address of the thread +register that contains the LSB of the vector, and the <wid> is the +size of the vector. The width must exactly match the width of the +signal.

+
    +
  • %set/qb <var-label>, <bit>, <wid>

  • +
  • %set/qf <var-label>, <bit>, <wid>

  • +
+

This sets the vector value into the back (qb) or front (qf) of a queue +variable.

+
    +
  • %shiftl <idx>

  • +
  • %shiftr <idx>

  • +
  • %shiftr/s <idx>

  • +
+

These instructions shift the top value in the vec4 stack left (towards +MSB) or right, possibly signed. The <idx> is the address of the index +register that contains the amount to shift.

+

The instruction also checks flag bit 4. If it is true, the result is +replaced with X instead of a shifted result. This is intended to +detect that the index contents were not valid.

+
    +
  • %split/vec4 <wid>

  • +
+

Pull the top vec4 vector from the stack and split it into two +parts. Split off <wid> bits from the LSB, then push the remaining bits +of the original (the MSB) back to the stack. Then push the split off +LSB vector.

+

The <wid> must be less than the width of the original, unsplit vector.

+
    +
  • %store/obj <var-label>

  • +
+

This pops the top of the object stack and writes it to the object +variable given by the label.

+

See also %load/obj.

+
    +
  • %store/prop/obj <pid>, <idx>

  • +
  • %store/prop/r <pid>

  • +
  • %store/prop/str <pid>

  • +
  • %store/prop/v <pid>, <wid>

  • +
+

The %store/prop/r pops a real value from the real stack and stores it +into the the property number <pid> of a cobject in the top of the +object stack. The cobject is NOT popped.

+

The %store/prop/obj pops an object from the top of the object stack, +then writes it to the property number <pid> of the cobject now on +top of the object stack. The cobject is NOT popped. The <idx> argument +is the index register to select an element. If the property is an +array, this selects the element. If <idx> is 0, then use the value 0 +instead of index register zero. Use 0 for non-array properties.

+

The %store/prop/v pops a vector from the vec4 stack and stores it into +the property <pid> of the cobject in the top of the object stack. The +vector is truncated to <wid> bits, and the cobject is NOT popped.

+
    +
  • %store/real <var-label>

  • +
  • %store/reala <var-label>, <index>

  • +
+

This pops the top of the real variable stack and write it to the +object variable given by the label.

+

The reala version is similar, but writes to a real array using the +index in the index register <index>

+
    +
  • %store/str <var-label>

  • +
  • %store/stra <array-label>, <index>

  • +
  • %store/dar/r <var-label>

  • +
  • %store/dar/str <var-label>

  • +
  • %store/dar/vec4 <var-label>

  • +
  • %store/qf/r <var-label>

  • +
  • %store/qf/str <var-label>

  • +
  • %store/qf/v <var-label>, <wid>

  • +
  • %store/qb/r <var-label>

  • +
  • %store/qb/str <var-label>

  • +
  • %store/qf/v <var-label>, <wid>

  • +
+

The %store/str instruction pops the top of the string stack and writes +it to the string variable.

+

The %store/stra targets an array.

+

The %store/dar/str is similar, but the target is a dynamic array of +string string. The index is taken from signed index register 3.

+
    +
  • %store/vec4 <var-label>, <offset>, <wid>

  • +
  • %store/vec4a <var-label>, <addr>, <offset>

  • +
+

Store a logic vector into the variable. The value (and its width) is +popped off the top of the stack and written to the variable. The value +is then optionally truncated to <wid> bits and assigned to the +variable. It is an error for the value to be fewer then <wid> +bits. The <offset> is the index register that contains a part offset +for writing into a part of the variable. If the <offset> is 0, then +use the literal value 0 instead of getting an offset from index +register 0.

+

The %store/vec4a is similar, but the target is an array of vec4, the +<addr> is an index register that contains the canonical address, and +the <offset> is an index register that contains the vector part +offset.

+

Both index registers can be 0, to mean a zero value instead of a zero +register.

+

The %store/vec4a will check flag bit 4, and if it is true, it will +suppress the actual assignment. This is so that the context can +indicate that the address is invalid.

+

The %store/vec4 will check flag bit 4, only if the <offset> is a +non-zero index register. A 0 index is a fixed constant and cannot +fail.

+

NOTE: The <wid> is not necessary, and should be removed.

+

The %store/qf/* and %store/qb/* instructions are queue manipulations, +which implement the push_back (qb) and push_front (qf) +functions. These only apply to queue object, and are distinct from the +dar versions because the begin/front don’t exist, by definition.

+
    +
  • %sub

  • +
+

This instruction subtracts vec4 values. The right value is popped from +the vec4 stack, then the left value is popped. The right is subtracted +from the left, and the result pushed.

+

See also the %add instruction.

+
    +
  • %subi <vala>, <valb>, <wid>

  • +
+

This instruction pops a value “A” from the vec4 stack, generates a +values “B” from the immediate argument, and pushes A-B.

+

See also the %addi instruction.

+
    +
  • %sub/wr

  • +
+

This instruction operates on real values in word registers. The right +value is popped, the left value is popped, the right is subtracted +from the left, and the result pushed.

+
    +
  • %substr <start>, <end>

  • +
+

This instruction takes the substring of the top string in the string +stack. This implements the SystemVerilog style substring. The string +stack is popped and replaced with the result.

+
    +
  • %substr/vec4 <sel>, <wid>

  • +
+

This instruction extracts the substring of the top string in the +string stack and pushes the result to the vec4 stack. The <sel> is the +index register that holds the select base, and the <wid> is the width, +in bits, of the result. Note that <wid> must be a multiple of 8.

+

The string value is NOT popped.

+
    +
  • %test_nul <var-label>

  • +
  • %test_nul/obj

  • +
  • %test_nul/prop <pid>, <idx>

  • +
+

This instruction tests the contents of the addressed variable to see +if it is null. If it is, set flag bit 4 to 1. Otherwise, set flag bit +4 to 0.

+

The %test_null/obj tests the object on the top of the stack, instead +of any variable. The value in the stack is NOT popped.

+

The %test_nul/prop instruction tests an object property for nul. The +object with the property is peeked from the top of the object stack, +and the <idx> is the array index if the property is an array of objects.

+

This is intended to implement the SystemVerilog expression +(<var>==null), where <var> is a class variable.

+
    +
  • %vpi_call <name> [, …] {<vec4> <real> <str>}

  • +
+

This instruction makes a call to a system task that was declared using +VPI. The operands are compiled down to a vpiHandle for the call. The +instruction contains only the vpiHandle for the call. See the vpi.txt +file for more on system task/function calls.

+

The {…} part is stack information. This tells the run-time how many +stack items the call uses so that it knows how many to pop off the +stack when the call returns.

+
    +
  • %vpi_func <file> <line> <name> [, …] {<vec4> <real> <str>}

  • +
  • %vpi_func/r <file> <line> <name> [, …] {<vec4> <real> <str>}

  • +
  • %vpi_func/s <file> <line> <name> [, …] {<vec4> <real> <str>}

  • +
+

This instruction is similar to %vpi_call, except that it is for +calling system functions. The difference here is the return value from +the function call is pushed onto the appropriate stack. The normal +means that the VPI code uses to write the return value causes those +bits to go here.

+

The {…} part is stack information. This tells the run-time how many +stack items the call uses from each stack so that it knows how many to +pop off the stack when the call returns. The function call will pop +the real and string stacks, and will push any return value.

+
    +
  • %wait <functor-label>

  • +
+

When a thread executes this instruction, it places itself in the +sensitive list for the addressed functor. The functor holds all the +threads that await the functor. When the defined sort of event occurs +on the functor, a thread schedule event is created for all the threads +in its list and the list is cleared.

+
    +
  • %wait/fork

  • +
+

This instruction puts the current thread to sleep until all the detached +children have finished executing. The last detached child is responsible +for restarting the parent when it finishes.

+
    +
  • %xnor

  • +
+

This instruction pops two vectors from the vec4 stack, does a bitwise +exclusive nor (~^) of the vectors, and pushes the result. The truth +table for the xor is:

+
+

0 xnor 0 –> 1 +0 xnor 1 –> 0 +1 xnor 0 –> 0 +1 xnor 1 –> 1 +otherwise x

+
+
    +
  • %xor

  • +
+

This instruction pops two vectors from the vec4 stack, does a bitwise +exclusive or (^) of the vectors, and pushes the result. The truth +table for the xor is:

+
+

0 xor 0 –> 0 +0 xor 1 –> 1 +1 xor 0 –> 1 +1 xor 1 –> 0 +otherwise x

+
+
/*
+ * Copyright (c) 2001-2024 Stephen Williams (steve@icarus.com)
+ *
+ *    This source code is free software; you can redistribute it
+ *    and/or modify it in source code form 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/vvp/vpi.html b/developer/guide/vvp/vpi.html new file mode 100644 index 0000000000..cee1617214 --- /dev/null +++ b/developer/guide/vvp/vpi.html @@ -0,0 +1,267 @@ + + + + + + + + + VPI Within VVP — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

VPI Within VVP

+

System tasks and functions in Verilog are implemented in Icarus +Verilog by C routines written with VPI. This implies that the vvp +engine must provide at least a subset of the Verilog VPI +interface. The minimalist concepts of vvp, however, make the method +less than obvious.

+

Within a Verilog design, there is a more or less fixed web of +vpiHandles that is the design database as is available to VPI +functions. The Verilog standard defines quite a lot of types, but the +vvp only implements the ones it needs. The VPI web is added into the +design using special pseudo-ops that create the needed objects.

+
+

Loading VPI Modules

+

The vvp runtime loads VPI modules at runtime before the parser reads +in the source files. This gives the modules a chance to register tasks +and functions before the source is compiled. This allows the compiler +to resolve references to system tasks and system functions to a +vpiHandle at compile time. References to missing tasks/function can +thus be caught before the simulation is run.

+
+

NOTE: This also, miraculously, allows for some minimal support of +the compiletf call. From the perspective of VPI code, compilation +of the VVP source is not unlike compilation of the original +Verilog.

+
+

The handle that the vvp threads have to the VPI are the vpiHandles of +the system tasks and functions. The %vpi_call instruction, once compiled, +carries the vpiHandle of the system task.

+
+
+

System Task Calls

+

A system task call invokes a VPI routine, and makes available to that +routine the arguments to the system task. The called routine gets +access to the system task call by calling back the VPI requesting the +handle. It uses the handle, in turn, to get hold of the operands for +the task.

+

All that vvp needs to know about a system task call is the handle of +the system task definitions (created by the vpi_register_systf +function) and the arguments of the actual call. The arguments are +tricky because the list has no bound, even though each particular call +in the Verilog source has a specific set of parameters.

+

Since each call takes a fixed number of parameters, the input source +can include in the statement the list of arguments. The argument list +will not fit in a single generated instruction, but a vpiHandle that +refers to a vpiSysTfCall does. Therefore, the compiler can take the +long argument list and form a vpiSysTaskCall object. The generated +instruction then only needs to be a %vpi_call with the single parameter +that is the vpiHandle for the call.

+
+
+

System Function Calls

+

System function calls are similar to system tasks. The only +differences are that all the arguments are input only, and there is a +single magic output that is the return value. The same %vpi_call can +even be used to call a function.

+

System functions, like system tasks, can only be called from thread +code. However, they can appear in expressions, even when that +expression is entirely structural. The desired effect is achieved by +writing a wrapper thread that calls the function when inputs change, +and that writes the output into the containing expression.

+
+
+

System Task/Function Arguments

+

The arguments to each system task or call are not stored in the +instruction op-code, but in the vpiSysTfCall object that the compiler +creates and that the %vpi_call instruction ultimately refers to. All +the arguments must be some sort of object that can be represented by a +vpiHandle at compile time.

+

Arguments are handled at compile time by the parser, which uses the +argument_list rule to build a list of vpiHandle objects. Each argument +in the argument_list invokes whatever function is appropriate for the +token in order to make a vpiHandle object for the argument_list. When +all this is done, an array of vpiHandles is passed to code to create a +vpiSysTfCall object that has all that is needed to make the call.

+
+
+

Scopes

+

VPI can access scopes as objects of type vpiScope. Scopes have names +and can also contain other sub-scopes, all of which the VPI function +can access by the vpiInternalScope reference. Therefore, the run-time +needs to form a tree of scopes into which other scoped VPI objects are +placed.

+

A scope is created with a .scope directive, like so:

+
<label> .scope "name" [, <parent>];
+        .timescale <units>;
+
+
+

The scope takes a string name as the first parameter. If there is an +additional parameter, it is a label of the directive for the parent +scope. Scopes that have no parent are root scopes. It is an error to +declare a scope with the same name more than once in a parent scope.

+

The name string given when creating the scope is the basename for the +scope. The vvp automatically constructs full names from the scope +hierarchy, and runtime VPI code can access that full name with the +vpiFullName reference.

+

The .timescale directive changes the scope units from the simulation +precision to the specified precision. The .timescale directive affects +the current scope.

+

Objects that place themselves in a scope place themselves in the +current scope. The current scope is the one that was last mentioned by +a .scope directive. If the wrong scope is current, the label on a +scope directive can be used to resume a scope. The syntax works like +this:

+
.scope <symbol>;
+
+
+

In this case, the <symbol> is the label of a previous scope directive, +and is used to identify the scope to be resumed. A scope resume +directive cannot have a label.

+
+
+

Variables

+

Reg vectors (scalars are vectors of length 1) are created by .var +statements in the source. The .var statement includes the declared +name of the variable, and the indices of the MSB and LSB of the +vector. The vpiHandle is then created with this information, and the +vpi_ipoint_t pointer to the LSB functor of the variable. VPI programs +access the vector through the vpiHandle and related functions. The VPI +code gets access to the declared indices.

+

The VPI interface to variable (vpiReg objects) uses the MSB and LSB +values that the user defined to describe the dimensions of the +object.

+
/*
+ * Copyright (c) 2001-2024 Stephen Williams (steve@icarus.com)
+ *
+ *    This source code is free software; you can redistribute it
+ *    and/or modify it in source code form 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/vvp/vthread.html b/developer/guide/vvp/vthread.html new file mode 100644 index 0000000000..e459c24651 --- /dev/null +++ b/developer/guide/vvp/vthread.html @@ -0,0 +1,177 @@ + + + + + + + + + Thread Details — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Thread Details

+

Thread objects in vvp are created by .thread statements in the +input source file.

+

A thread object includes a program counter and private bit +registers. The program counter is used to step the processor through +the code space as it executes instructions. The bit registers each +hold Verilog-style 4-value bits and are for use by the arithmetic +operators as they operate.

+

The program counter normally increments by one instruction after the +instruction is fetched. If the instruction is a branching instruction, +then the execution of the instruction sets a new value for the pc.

+

Instructions that use the bit registers have as an operand a <bit> +value. There is usually space in the instruction for 2 <bit> +operands. Instructions that work on vectors pull the vector values +from the bit registers starting with the LSB and up.

+

The bit addresses 0, 1, 2 and 3 are special constant bits 0, 1, x and +z, and are used as read-only immediate values. If the instruction +takes a single bit operand, then the appropriate value is simply read +out. If the instruction expects a vector, then a vector of the +expected width is created by replicating the constant value.

+

Bits 4, 5, 6 and 7 are read/write bits but are reserved by many +instructions for special purposes. Comparison operators, for example, +use these as comparison flag bits.

+

The remaining 64K-8 possible <bit> values are read-write bit registers +that can be accessed singly or as vectors. This obviously implies that +a bit address is 16 bits.

+

Threads also contain 16 numeric registers. These registers can hold a +real value or a 64bit integer, and can be used in certain cases where +numeric values are needed. The thread instruction set includes +%ix/* instructions to manipulate these registers. The instructions +that use these registers document which register is used, and what the +numeric value is used for. Registers 0-3 are often given fixed +meanings to instructions that need an integer value.

+
/*
+ * Copyright (c) 2001-2024 Stephen Williams (steve@icarus.com)
+ *
+ *    This source code is free software; you can redistribute it
+ *    and/or modify it in source code form 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/guide/vvp/vvp.html b/developer/guide/vvp/vvp.html new file mode 100644 index 0000000000..cad516faf3 --- /dev/null +++ b/developer/guide/vvp/vvp.html @@ -0,0 +1,1217 @@ + + + + + + + + + VVP Simulation Engine — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

VVP Simulation Engine

+

The VVP simulator takes as input source code not unlike assembly +language for a conventional processor. It is intended to be machine +generated code emitted by other tools, including the Icarus Verilog +compiler, so the syntax, though readable, is not necessarily +convenient for humans.

+
+

General Format

+

The source file is a collection of statements. Each statement may have +a label, an opcode, and operands that depend on the opcode. For some +opcodes, the label is optional (or meaningless) and for others it is +required.

+

Every statement is terminated by a semicolon. The semicolon is also +the start of a comment line, so you can put comment text after the +semicolon that terminates a statement. Like so:

+
Label .functor and, 0x5a, x, y  ; This is a comment.
+
+
+

The semicolon is required, whether the comment is there or not.

+

Statements may span multiple lines, as long as there is no text (other +then the first character of a label) in the first column of the +continuation line.

+
+
+

Header Syntax

+

Before any other non-commentary code starts, the source may contain +some header statements. These are used for passing parameters or +global details from the compiler to the vvp run-time. In all cases, +the header statement starts with a left-justified keyword.

+
    +
  • :module “name” ;

  • +
+

This header statement names a vpi module that vvp should load before +the rest of the program is compiled. The compiler looks in the +standard VPI_MODULE_PATH for files named “name.vpi”, and tries to +dynamic load them.

+
    +
  • :vpi_time_precision [+|-]<value>;

  • +
+

This header statement specifies the time precision of a single tick of +the simulation clock. This is mostly used for display (and VPI) +purposes, because the engine itself does not care about units. The +compiler scales time values ahead of time.

+

The value is the size of a simulation tick in seconds, and is +expressed as a power of 10. For example, +0 is 1 second, and -9 is 1 +nanosecond. If the record is left out, then the precision is taken to +be +0.

+
+
+

Labels and Symbols

+

Labels and symbols consist of the characters:

+
a-z
+A-Z
+0-9
+.$_<>
+
+
+

Labels and symbols may not start with a digit or a ‘.’, so that they +are easily distinguished from keywords and numbers. A Label is a +symbol that starts a statement. If a label is present in a statement, +it must start in the first text column. This is how the lexical +analyzer distinguishes a label from a symbol. If a symbol is present +in a statement, it is in the operand. Opcodes of statements must be a +keyword.

+

Symbols are references to labels. It is not necessary for a label to +be declared before its use in a symbol, but it must be declared +eventually. When symbols refer to functors, the symbol represents the +vvp_ipoint_t pointer to the output. (Inputs cannot, and need not, be +references symbolically.)

+

If the functor is part of a vector, then the symbol is the +vvp_ipoint_t for the first functor. The [] operator can then be used +to reference a functor other than the first in the vector.

+

There are some special symbols that in certain contexts have special +meanings. As inputs to functors, the symbols “C<0>”, “C<1>”, “C<x>” +and “C<z>” represent a constant driver of the given value.

+
+
+

Numbers

+

decimal number tokens are limited to 64bits, and are unsigned. Some +contexts may constrain the number size further.

+
+
+

Scope Statements

+

The syntax of a scope statement is:

+
<label> .scope <type>, <name> <type-name> <file> <lineno> ;
+
+<label> .scope <type>, <name> <type-name> <file> <lineno>, \
+               <def-file> <def-lineno> <is-cell>, <parent> ;
+
+
+

The <type> is the general type of the scope: module, autofunction, +function, autotask, task, begin, fork, autobegin, autofork, or generate.

+

The <name> is a string that is the base name of the instance. For +modules, this is the instance name. For tasks and functions, this is +the task or function name.

+

The <type-name> is the name of the type. For most scope types, this is +the name as the <name>, but for module and class scopes, this is the +name of the definition, and not the instance.

+

The <file> and <lineno> are the location of the instantiation of this +scope. For a module, it is the location of the instance.

+

The <def-file> and <def-lineno> is the source file and line number for +the definition of the scope. For modules, this is where the module is +defined instead of where it is instantiated.

+

The <is-cell> flag is only useful for module instances. It is true +(not zero) if the module is a celltype instead of a regular module.

+

The short form of the scope statement is only used for root scopes.

+
+
+

Parameter Statements

+

Parameters are named constants within a scope. These parameters have a +type and value, and also a label so that they can be referenced as VPI +objects.

+

The syntax of a parameter is:

+
<label> .param/str <name> <local-flag> <file-idx> <lineno>, <value>;
+<label> .param/l <name> <local-flag> <file-idx> <lineno>, <value>;
+<label> .param/r <name> <local-flag> <file-idx> <lineno>, <value>;
+
+
+

The <name> is a string that names the parameter. The name is placed in +the current scope as a vpiParameter object. The .param suffix +specifies the parameter type:

+
.param/str    -- The parameter has a string value
+.param/l      -- The parameter has a logic vector value
+.param/r      -- The parameter has a real value
+
+
+

The value, then, is appropriate for the data type. For example:

+
P_123 .param/str "hello", "Hello, World.";
+
+
+

The boolean and logic values can also be signed or not. If signed, the +value is preceded by a ‘+’ character. (Note that the value is 2s +complement, so the ‘+’ says only that it is signed, not positive.)

+
+
+

Functor Statements

+

A functor statement is a statement that uses the .functor +opcode. Functors are the basic structural units of a simulation, and +include a type (in the form of a truth table) and up to four inputs. A +label is required for functors.

+

The general syntax of a functor is:

+
<label> .functor <type>, symbol_list ;
+<label> .functor <type> [<drive0> <drive1>], symbol_list ;
+
+
+

The symbol list is 4 names of labels of other functors. These connect +inputs of the functor of the statement to the output of other +functors. If the input is unconnected, use a C<?> symbol instead. The +type selects the truth lookup table to use for the functor +implementation. Most of the core gate types have built in tables.

+

The initial values of all the inputs and the output is x. Any other +value is passed around as run-time behavior. If the inputs have C<?> +symbols, then the inputs are initialized to the specified bit value, +and if this causes the output to be something other than x, a +propagation event is created to be executed at the start of run time.

+

The strengths of inputs are ignored by functors, and the output has +fixed drive0 and drive1 strengths. So strength information is +typically lost as it passes through functors.

+

Almost all of the structural aspects of a simulation can be +represented by functors, which perform the very basic task of +combining up to four inputs down to one output.

+
    +
  • MUXZ

  • +
+
Q | A  B  S  n/a
+--+-------------
+A | *  *  0
+B | *  *  1
+
+
+
+
+

DFF and Latch Statements

+

The Verilog language itself does not have a DFF primitive, but post +synthesis readily creates DFF devices that are best simulated with a +common device. Thus, there is the DFF statement to create DFF devices:

+
<label> .dff/p <width> <d>, <clk>, <ce>;
+<label> .dff/n <width> <d>, <clk>, <ce>;
+<label> .dff/p/aclr <width> <d>, <clk>, <ce>, <async-input>;
+<label> .dff/n/aclr <width> <d>, <clk>, <ce>, <async-input>;
+<label> .dff/p/aset <width> <d>, <clk>, <ce>, <async-input>[, <set-value>];
+<label> .dff/n/aset <width> <d>, <clk>, <ce>, <async-input>[, <set-value>];
+
+
+

The /p variants simulate positive-edge triggered flip-flops and the +/n variants simulate negative-edge triggered flip-flops. The generated +functor is generally synchronous on the specified edge of <clk>, with +the <ce> enable active high. The <clk> and <ce> are single bit vectors +(or scalars) on ports 1 and 2. Port-0 is any type of datum at all. The +device will transfer the input to the output when it is loaded by a +clock. The <async-input> is a special asynchronous input that on the +rising edge causes the device to clear/set, forces the output to +propagate, and disables the clock until the aynchronous input is +deasserted. Thus, they implement DFF with asynchronous clr or set.

+

Similarly, synthesis creates D-type latches, so there is the LATCH +statement to support this:

+
<label> .latch <width> <d>, <en>;
+
+
+

The <en> is a single bit vector (or scalar) on port-1. Port-0 is any +type of datum at all. The device will transfer the input to the output +whenever <en> is a logic 1.

+
+
+

UDP Statements

+

A UDP statement either defines a User Defined Primitive, or +instantiates a previously defined UDP by creating a UDP functor. A +UDP functor has as many inputs as the UDP definition requires.

+

UDPs come in sequential and combinatorial flavors. Sequential UDPs +carry an output state and can respond to edges at the inputs. The +output of combinatorial UDPs is a function of its current inputs +only.

+

The function of a UDP is defined via a table. The rows of the table +are strings which describe input states or edges, and the new output +state. Combinatorial UDPs require one character for each input, and +one character at the end for the output state. Sequential UDPs need +an additional char for the current state, which is the first char of +the row.

+

Any input transition or the new state must match at most one row (or +all matches must provide the same output state). If no row matches, +the output becomes 1’bx.

+

The output state can be specified as “0”, “1”, or “x”. Sequential +UDPs may also have “-”: no change.

+

An input or current output state can be

+
"1": 1
+"0": 0
+"x": x
+"b": 1, 0
+"h": 1, x
+"l": 0, x
+"?": 1, 0, x
+
+
+

For Sequential UDPs, at most one input state specification may be +replaced by an edge specification. Valid edges are:

+
"*": (??)       "_": (?0)       "+": (?1)       "%": (?x)
+"P": (0?)                       "r": (01)       "Q": (0x)
+"N": (1?)       "f": (10)                       "M": (1x)
+"B": (x?)       "F": (x0)       "R": (x1)
+
+"n": (1?) | (?0)
+"p": (0?) | (?1)
+
+
+

A combinatorial UDP is defined like this:

+
<type> .udp/comb "<name>", <number>, "<row0>", "<row1>", ... ;
+
+
+

<type> is a label that identifies the UDP. <number> is the number of +inputs. “<name>” is there for public identification. Sequential UDPs +need an additional initialization value:

+
<type> .udp/sequ "<name>", <number>, <init>, "<row0>", "<row1>", ... ;
+
+
+

<init> is the initial value for all instances of the UDP. We do not +provide initial values for individual instances. <init> must be a +number 0, 1, or 2 (for 1’bx).

+

A UDP functor instance is created so:

+
<label> .udp  <type>, <symbol_list> ;
+
+
+

Where <label> identifies the functor, <type> is the label of a UDP +defined earlier, and <symbol_list> is a list of symbols, one for each +input of the UDP.

+
+
+

Variable Statements

+

A variable is a bit vector that can be written by behavioral code (so +has no structural input) and propagates its output to a functor. The +general syntax of a variable is:

+
<label> .var   "name", <msb> <lsb>; Unsigned logic variable
+<label> .var/s "name", <msb> <lsb>; Signed logic variable
+<label> .var/2u "name", <msb> <lsb>; Unsigned bool/bit variable
+<label> .var/2s "name", <msb> <lsb>; Signed bool/bit variable
+<label> .var/real "name", <msb>, <lsb>; real variable
+<label> .var/i "name", <msb>, <lsb>; vpiIntegerVar variable
+<label> .var/str "name"; vpiStringVar variable
+
+
+

The “name” is the declared base name of the original variable, for the +sake of VPI code that might access it. The variable is placed in the +current scope. The variable also has a width, defined by the indices +for the most significant and lest significant bits. If the indices are +equal (normally 0) the vector has width of one. If the width is greater +then one, a contiguous array of functors is created and the value of +the label is the address of the least significant bit.

+

A variable does not take inputs, since its value is set behaviorally +by assignment events. It does have output, though, and its output is +propagated into the net of functors in the usual way.

+

A variable gets its value by assignments from procedural code: %set +and %assign. These instructions write values to the port-0 input. From +there, the value is held.

+

Behavioral code can also invoke %cassign/v statements that work like +%set/v, but instead write to port-1 of the variable node. Writes to +port-1 of a variable activate continuous assign mode, where the values +written to port-0 are ignored. The continuous assign mode remains +active until a long(1) is written to port-3 (a command port).

+

Behavioral code may also invoke %force/v statements that write to port-2 +to invoke force mode. This overrides continuous assign mode until a +long(2) is written to port-3 to disable force mode.

+
+
+

Net Statements

+

A net is similar to a variable, except that a thread cannot write to +it (unless it uses a force) and it is given a different VPI type +code. The syntax of a .net statement is also similar to but not +exactly the same as the .var statement:

+
<label> .net      "name", <msb>, <lsb>, <symbol>;
+<label> .net/s    "name", <msb>, <lsb>, <symbol>;
+<label> .net8     "name", <msb>, <lsb>, <symbol>;
+<label> .net8/s   "name", <msb>, <lsb>, <symbol>;
+<label> .net/real "name", <msb>, <lsb>, <symbol>;
+
+
+

Like a .var statement, the .net statement creates a VPI object with +the basename and dimensions given as parameters. The symbol is a +functor that feeds into the vector of the net, and the vpiHandle +holds references to that functor.

+

The input of a .net is replicated to its output. In this sense, it +acts like a diode. The purpose of this node is to hold various VPI +and event trappings. The .net and .net8 nodes are vector types. They +both may represent wires, but the .net8 nodes preserve strength values +that arrive through them, while .net nodes reduce strength values to +4-value logic. The .net8 nodes should only be used when strength +information really is possible.

+

The <label> is required and is used to locate the net object that it +represents. This label does not map to a functor, so only references +that know they want to access .nets are able to locate the symbol. In +particular, this includes behavioral %load and %wait instructions. The +references to net and reg objects are done through the .net label +instead of a general functor symbol. The instruction stores the +functor pointer, though.

+

The .alias statements do not create new nodes, but instead create net +names that are aliases of an existing node. This handles special cases +where a net has different names, possibly in different scopes.

+
+
+

Cast Statements

+

Sometimes nets need to be cast from a real valued net to a bit based +net or from a bit based net to a real valued net. These statements +are used to perform that operation:

+
<label> .cast/int <width>, <symbol>;
+<label> .cast/2 <width>, <symbol>;
+<label> .cast/real <symbol>;
+<label> .cast/real.s <symbol>;
+
+
+

For .cast/int the output <label> is a bit based net that is <width> +bits wide. The input <symbol> is expected to put real values to +this functor.

+

For .cast/real the output <label> is a real valued net. The input +<symbol> is expected to put bit based values and for .cast/real.s +the bits will be interpreted as a signed value.

+
+
+

Delay Statements

+

Delay nodes are structural net delay nodes that carry and manage +propagation delays. Delay nodes can have fixed delays or variable +delays. Fixed delay nodes have only the input that is to be +delayed. The delay amount is given on the node line. Variable delay +nodes have three extra inputs to receive the rise, fall and decay +times that are used for delay.

+
.delay <width> ( <rise>, <fall>, <decay> ) <input> ;
+.delay <width> <input>, <rise>, <fall>, <decay> ;
+
+
+

The first form above takes three constant (64bit) numbers as the +initial delay, and takes a single input. The second form takes 4 net +inputs, with the first being the value to delay, and the remaining to +be the delay values to use. <width> specifies the bit width of the +input net, with a width of 0 used to identify a real valued net.

+
+
+

Module Path Delay Statements

+

A module path delay takes data from its input, then a list of module +path delays. The <src> for each possible delay set is a trigger that +activates the delay.

+
.modpath <width> <input> , [ <src> (<delays> [? <condition>]) ] ;
+
+
+

<width> specifies the bit width of the input net.

+
+
+

Array Index Statements

+

Variables can be collected into arrays. The words of the array are +declared separately, this statement collects them together:

+
<label> .array "name", <last> <first> ;
+
+
+

the .var or .net statements after this array statement, that have the +same “name” are collected, in order, as words.

+

The syntax below is different, in that it creates an alias for an +existing array. The dimensions and storage are taken from the .array +at <src>.

+
<label> .array "name", <src> ;
+
+
+
+
+

Event Statements

+

Threads need to interact with the functors of a netlist synchronously, +as well as asynchronously. There are cases where the web of functors +needs to wake up a waiting thread. The web of functors signals threads +through .event objects, that are declared like so:

+
<label> .event <type>, <symbols_list>;
+<label> .event "name";
+
+
+

This event statement declares an object that a %wait instruction +can take as an operand. When a thread executes a %wait, it puts +itself in the notification list of the event and suspends. The +<symbols_list> is a set of inputs that can trigger the event.

+

The <type> describes the conditions needed to trigger the event. It +may be posedge, negedge, edge or anyedge. If the type is instead a +“name” string, then this is a named event which receives events by +the %set instruction instead of from the output of a functor.

+

If the event has inputs (a requirement unless it is a named event) +then it has up to 4 symbols that address functors. The event then +detects the appropriate edge on any of the inputs and signals when the +event is true. Normally (in Verilog) a posedge or negedge event only +watches a single bit, so the generated code would only include a +single symbol for the addressed bit. However, if there are several +events of the same edge in an event OR expression, the compiler may +combine up to 4 into a single event.

+

If many more events need to be combined together (for example due to +an event or expression in the Verilog) then this form can be used:

+
<label> .event/or <symbols_list>;
+
+
+

In this case, the symbols list all the events that are to be combined +to trigger this event. Only one of the input events needs to trigger +to make this one go.

+
+
+

Resolver Statements

+

Resolver statements are strength-aware functors with 4 inputs, but +their job typically is to calculate a resolved output using strength +resolution. The type of the functor is used to select a specific +resolution function.

+
<label> .resolv tri,  <symbols_list>;
+<label> .resolv tri0, <symbols_list>;
+<label> .resolv tri1, <symbols_list>;
+
+
+

The output from the resolver is vvp_vector8_t value. That is, the +result is a vector with strength included.

+
+
+

Part Select Statements

+

Part select statements are functors with three inputs. They take in at +port-0 a vector, and output a selected (likely smaller) part of that +vector. The other inputs specify what those parts are, as a canonical +bit number, and a width. Normally, those bits are constant values.

+
<label> .part <symbol>, <base>, <wid>;
+<label> .part/pv <symbol>, <base>, <wid>, <vector_wid>;
+<label> .part/v <symbol>, <symbol>, <wid>;
+<label> .part/v.s <symbol>, <symbol>, <wid>;
+
+
+

The input is typically a .reg or .net, but can be any vector node in +the netlist.

+

The .part/pv variation is the inverse of the .part version, in that +the output is actually written to a part of the output. The node +uses special part-select-write functions to propagate a part of a +network. The <vector_wid> is the total width of the destination net +that part is written to. Destination nodes use this value to check +further output widths.

+

The .part/v variation takes a vector (or long) input on port-1 as the +base of the part select. Thus, the part select can move around. The +.part/v.s variation treats the vector as a signed value.

+
+
+

Part Concatenation Statements

+

The opposite of the part select statement is the part concatenation +statement. The .concat statement is a functor node that takes at input +vector values and produces a single vector output that is the +concatenation of all the inputs.

+
<label> .concat [W X Y Z], <symbols_list> ;
+
+
+

The “[” and “]” tokens surround a set of 4 numbers that are the +expected widths of all the inputs. These widths are needed to figure +the positions of the input vectors in the generated output, and are +listed in order LSB to MSB. The inputs themselves are also listed LSB +to MSB, with the LSB vector input coming through port-0 of the real +functor.

+

The initial output value is (W+X+Y+Z) bits of ‘bx. As input values are +propagated, the bits are placed in the correct place in the output +vector value, and a new output value is propagated.

+
+
+

Repeat Vector Statements

+

The repeat vector statement is similar to the concatenation statement, +expect that the input is repeated a constant number of times. The +format of the repeat vector statement is:

+
<label> .repeat <wid>, <rept count>, <symbol> ;
+
+
+

In this statement, the <wid> is a decimal number that is the width of +the output vector. The <rept count> is the number of time the input +vector value is repeated to make the output width. The input width is +implicit from these numbers. The <symbol> is then the input source.

+
+
+

Substitution Statements

+

The substitution statement doesn’t have a direct analog in Verilog, it +only turns up in synthesis. It is a shorthand for forms like this:

+
foo = <a>;
+foo[n] = <s>;
+
+
+

The format of the substitute statement is:

+
<label> .substitute <wid>, <soff> <swid>, <symbol>, <symbol> ;
+
+
+

The first <symbol> must have the width <wid>, and is passed through, +except for the bits within [<soff> +: <swid>]. The second <symbol> +collects a vector that goes into that part.

+
+
+

Reduction Logic

+

The reduction logic statements take in a single vector, and propagate +a single bit.

+
<label> .reduce/and  <symbol> ;
+<label> .reduce/or   <symbol> ;
+<label> .reduce/xor  <symbol> ;
+<label> .reduce/nand <symbol> ;
+<label> .reduce/nor  <symbol> ;
+<label> .reduce/xnor <symbol> ;
+
+
+

the device has a single input, which is a vector of any width. The +device performs the logic on all the bits of the vector (a la Verilog) +and produces and propagates a single bit width vector.

+
+
+

Expansion Logic

+

Sign extension nodes are the opposite of reduction logic, in that they +take a narrow vector, or single bit, and pad it out to a wider +vector.

+
<label> .expand/s <wid>, <symbol> ;
+
+
+

The .expand/s node takes an input symbol and sign-extends it to the +given width.

+
+
+

Force Statements (old method - remove me)

+

A force statement creates functors that represent a Verilog force +statement.

+
<label> .force <signal>, <symbol_list>;
+
+
+

The symbol <signal> represents the signal which is to be forced. The +<symbol_list> specifies the bits of the expression that is to be +forced on the <signal>. The <label> identifies the force functors. +There will be as many force functors as there are symbols in the +<symbol_list>.

+

To activate and deactivate a force on a single bit, use:

+
%force  <label>, <width>;
+%release <signal>;
+
+
+

<label>/<width> is the label/width of a vector of force functors. +<signal> is the label of the functor that drives the signal that is +being forced.

+
+
+

Force Statements (new method - implement me)

+

A %force instruction, as described in the .var section, forces a +constant value onto a .var or .net, and the matching %release releases +that value. However, there are times when the value of a functor +(i.e. another .net) needs to be forced onto a .var or .net. For this +task, the %force/link instruction exists:

+
%force/link <dst>, <src> ;
+%release/link <dst> ;
+
+
+

This causes the output of the node <src> to be linked to the force +input of the <dst> .var/.net node. When linked, the output functor +will automatically drive values to the force port of the destination +node. The matching %release/link instruction removes the link (a +%release is still needed) to the destination. The %release/link +releases the last %force/link, no matter where the link is from. A new +%force/link will remove a previous link.

+

The instructions:

+
%cassign/link <dst>, <src> ;
+%deassign/link <dst> ;
+
+
+

are the same concept, but for the continuous assign port.

+
+
+

Structural Arithmetic Statements

+

The various Verilog arithmetic operators (+-*/%) are available to +structural contexts as two-input functors that take in vectors. All of +these operators take two inputs and generate a fixed width output. The +input vectors will be padded if needed to get the desired output width.

+
<label> .arith/sub  <wid>, <A>, <B>;
+<label> .arith/sum  <wid>, <A>, <B>;
+<label> .arith/mult <wid>, <A>, <B>;
+<label> .arith/div  <wid>, <A>, <B>;
+<label> .arith/mod  <wid>, <A>, <B>;
+
+
+

In all cases, there are no width limits, so long as the width is +fixed.

+

NOTE: The .arith/mult inputs are not necessarily the width of the +output. I have not decided how to handle this.

+

These devices support .s and .r suffixes. The .s means the node is a +signed vector device, the .r a real valued device.

+
+
+

Structural Compare Statements

+

The arithmetic statements handle various arithmetic operators that +have wide outputs, but the comparators have single bit output, so they +are implemented a bit differently. The syntax, however, is very +similar:

+
<label> .cmp/eeq <wid>, <A>, <B>;
+<label> .cmp/nee <wid>, <A>, <B>;
+<label> .cmp/eq  <wid>, <A>, <B>;
+<label> .cmp/ne  <wid>, <A>, <B>;
+<label> .cmp/ge  <wid>, <A>, <B>;
+<label> .cmp/gt  <wid>, <A>, <B>;
+<label> .cmp/ge.s <wid>, <A>, <B>;
+<label> .cmp/gt.s <wid>, <A>, <B>;
+<label> .cmp/weq <wid>, <A>, <B>;
+<label> .cmp/wne <wid>, <A>, <B>;
+
+
+

Whereas the arithmetic statements generate an output the width of +<wid>, the comparisons produce a single bit vector result. The plain +versions do unsigned comparison, but the “.s” versions to signed +comparisons. (Equality doesn’t need to care about sign.)

+
+
+

Structural Shifter Statements

+

Variable shifts in structural context are implemented with .shift +statements:

+
<label> .shift/l <wid>, <data symbol>, <shift symbol>;
+<label> .shift/r <wid>, <data symbol>, <shift symbol>;
+
+
+

The shifter has a width that defines the vector width of the output, a +<data symbol> that is the input data to be shifted and a <shift-symbol> +that is the amount to shift. The vectors that come from port 0 are the +data to be shifted and must have exactly the width of the output. The +input to port 1 is the amount to shift.

+
+
+

Structural Function Calls

+

The .ufunc statements define a call to a user defined function.

+
<label> .ufunc/real <flabel>, <wid>,
+    [<isymbols> ( <psymbols> )] <ssymbol>;
+
+<label> .ufunc/vec4 <flabel>, <wid>,
+    [<isymbols> ( <psymbols> )] <ssymbol>;
+
+<label> .ufunc/e <flabel>, <wid>, <trigger>,
+    <isymbols> ( <psymbols> ) <ssymbol>;
+
+
+

The first variant is used for functions that only need to be called +when one of their inputs changes value. The second variant is used +for functions that also need to be called when a trigger event occurs.

+

The <flabel> is the code label for the first instruction of the +function implementation. This is code that the simulator will branch +to.

+

The <wid> is the width of the output vector in bits.

+

The <trigger> is the label for the trigger event.

+

The <isymbols> is a list of net symbols for each of the inputs to the +function. These are points in the net, and the ufunc device watches +these nets for input changes.

+

The <psymbols> list is exactly the same size as the <isymbols> +list. The <psymbols> are variables that represent the input ports for +the function. The ufunc performs an assignment to these variables +before calling the function.

+

The <ssymbol> is the function scope name.

+
+
+

Thread Statements

+

Thread statements create the initial threads for a simulation. These +represent the initial and always blocks, and possibly other causes to +create threads at startup.

+
.thread <symbol> [, <flag>]
+
+
+

This statement creates a thread with a starting address at the +instruction given by <symbol>. When the simulation starts, a thread is +created for the .thread statement, and it starts at the <symbol> +addressed instruction.

+

The <flag> modifies the creation/execution behavior of the +thread. Supported flags are:

+
$push -- Cause the thread to be pushed in the scheduler. This
+         only effects startup (time 0) by arranging for pushed
+         threads to be started before non-pushed threads. This
+         is useful for resolving time-0 races.
+
+
+
    +
  • Threads in general

  • +
+

Thread statements create the initial threads of a design. These +include the initial and always statements of the original +Verilog, and possibly some other synthetic threads for various +purposes. It is also possible to create transient threads from +behavioral code. These are needed to support such constructs as +fork/join, named blocks and task activation.

+

A transient thread is created with a %fork instruction. When a +transient thread is created this way, the operand to the %fork gives +the starting address, and the new thread is said to be a child of the +forking thread. The children of a thread are pushed onto a stack of +children. A thread can have only one direct child.

+

A transient thread is reaped with a %join instruction. %join waits for +the top thread in the stack of children to complete, then +continues. It is an error to %join when there are no children.

+

As you can see, the transient thread in VVP is a cross between a +conventional thread and a function call. In fact, there is no %call +instruction in vvp, the job is accomplished with %fork/%join in the +caller and %end in the callee. The %fork, then is simply a +generalization of a function call, where the caller does not +necessarily wait for the callee.

+

For all the behavior of threads and thread parentage to work +correctly, all %fork statements must have a corresponding %join in the +parent, and %end in the child. Without this proper matching, the +hierarchical relationships can get confused. The behavior of erroneous +code is undefined.

+
    +
  • Thread Context

  • +
+

The context of a thread is all the local data that only that thread +can address. The local data is broken into two address spaces: bit +memory and word memory.

+

The bit memory is a region of 4-value bits (0,1,x,z) that can be +addressed in strips of arbitrary length. For example, an 8-bit value +can be in locations 8 through and including 15. The bits at address 0, +1, 2 and 3 are special constant values. Reads from those locations +make vectors of 0, 1, x or z values, so these can be used to +manufacture complex values elsewhere.

+

The word memory is a region of tagged words. The value in each word +may be either a 64-bit unsigned integer (uint64_t), a 64-bit signed +integer (int64_t), or a 64-bit floating point number (double). These +words have a distinct address space from the bits.

+
    +
  • Threads and scopes

  • +
+

The Verilog disable statement deserves some special mention +because of how it interacts with threads. In particular, threads +throughout the design can affect (end) other threads in the design +using the disable statement.

+

In Verilog, the operand to the disable statement is the name of a +scope. The behavior of the disable is to cause all threads executing +in the scope to end. Termination of a thread includes all the children +of the thread. In vvp, all threads are in a scope, so this is how the +disable gains access to the desired thread.

+

It is obvious how initial/always thread join a scope. They become part +of the scope simply by being declared after a .scope declaration. (See +vvp.txt for .scope declarations.) The .thread statement placed in the +assembly source after a .scope statement causes the thread to join the +named scope.

+

Transient threads join a scope that is the operand to the %fork +instruction. The scope is referenced by name, and the thread created +by the fork atomically joins that scope. Once the transient thread +joins the scope, it stays there until it ends. Threads never change +scopes, not even transient threads.

+
+
+

Vpi Task/Function Calls

+

Threads call vpi tasks with the %vpi_call or %vpi_func +instructions. The formats are:

+
%vpi_call <file-index> <lineno> <name>, <args>... ;
+%vpi_call/w <file-index> <lineno> <name>, <args>... ;
+%vpi_call/i <file-index> <lineno> <name>, <args>... ;
+%vpi_func <file-index> <lineno> <name>, <args>... ;
+%vpi_func/r <file-index> <lineno> <name>, <args>... ;
+%vpi_func/s <file-index> <lineno> <name>, <args>... ;
+
+
+

The <file-index> is an index into the string table. The indexed string +is the source code file name where this call appears. The <lineno> is +the line number from the source code where this task/function appears.

+

The <name> is a string that is the name of the system +task/function. For example, “$display”, $strobe”, etc. This name is +looked up and compared with the registered system tasks/functions.

+

The <args>… is a comma (“,”) separated list of arguments. These are +made available to the VPI code as vpi handles.

+

The plain %vpi_call will fail with an error message if a system function +is called as a task. The /w suffix version will display a warning message +if a system function is called as a task and will ignore any value that +the function tries to return. The /i suffix version silently ignores any +value returned by a system function called as a task.

+
    +
  • The &A<> argument

  • +
+

The &A<> argument is a reference to the word of a variable array. The +syntax is:

+
&A '<' <symbol> , <number> '>'
+&A '<' <symbol> , <base_symbol> '>'
+&A '<' <symbol> , <base> <width> <"s" or "u"> '>'
+
+
+

The <symbol> is the label for a variable array, and the <number> is +the canonical word index as an unsigned integer. The second form +retrieves the <base> from the given signal or &A<>/&PV<> select. +The third form retrieves the index from thread space (<width> bits +starting at <base>). The base value may be signed or unsigned.

+
    +
  • The &PV<> argument

  • +
+

The &PV<> argument is a reference to part of a signal. The syntax is:

+
&PV '<' <symbol> , <base> , <width> '>'
+&PV '<' <symbol> , <base_symbol> , <width> '>'
+&PV '<' <symbol> , <tbase> <twid> <"s" or "u"> , <width> '>'
+
+
+

The <symbol> is the label for a signal, the <base> is the canonical +starting bit of the part select and <width> is the number of bits in +the select. The second form retrieves the <base> from the given signal +or &A<>/&PV<> select. The third form retrieves the <base> from thread +space using <twid> bits starting at <tbase>. The base value may be +signed or unsigned.

+
+
+

Truth Tables

+

The logic that a functor represents is expressed as a truth table. The +functor has four inputs and one output. Each input and output has one +of four possible values (0, 1, x and z) so two bits are needed to +represent them. So the input of the functor is 8 bits, and the output +2 bits. A complete lookup table for generating the 2-bit output from +an 8-bit input is 512 bits. That can be packed into 64 bytes. This is +small enough that the table should take less space than the code to +implement the logic.

+

To implement the truth table, we need to assign 2-bit encodings for +the 4-value signals. I choose, pseudo-randomly, the following +encoding:

+
1'b0  : 00
+1'b1  : 01
+1'bx  : 10
+1'bz  : 11
+
+
+

The table is an array of 64 bytes, each byte holding 4 2-bit +outputs. Construct a 6-bit byte address with inputs 1, 2 and 3 like +so:

+
332211
+
+
+

The input 0 2-bits can then be used to select which of the 4 2-bit +pairs in the 8-bit byte are the output:

+
MSB -> zzxx1100 <- LSB
+
+
+

A complete truth table, then is described as 64 8-bit bytes.

+

The vvp engine includes truth tables for the primitive gate types, so +none needs to be given by the programmer. It is sufficient to name the +type to get that truth table.

+
+
+

Executable Instructions

+

Threads run executable code, much like a processor executes machine +code. VVP has a variety of opcodes for executable instructions. All of +those instructions start with ‘%’ and go into a single address +space. Labels attached to executable instructions get assigned the +address of the instruction, and can be the target of %jmp instructions +and starting points for threads.

+

The opcodes.txt file has a more detailed description of all the +various instructions.

+
+
+

The Relationship Between Functors, Threads And Events

+

Given the above summary of the major components of vvp, some +description of their relationship is warranted. Functors provide a +structural description of the design (so far as it can be described +structurally) and these functors run independently of the threads. In +particular, when an input to a functor is set, it calculates a new +output value; and if that output is different from the existing +output, a propagation event is created. Functor output is calculated +by truth table lookup, without the aid of threads.

+

Propagation events are one of three kinds of events in vvp. They are +scheduled to execute at some time, and they simply point to the functor +that is to have its output propagated. When the event expires, the +output of the referenced functor is propagated to all the inputs that +it is connected to, and those functors in turn create new events if +needed.

+

Assignment events (the second of three types of events) are created +by non-blocking assignments in behavioral code. When the <= is +executed (a %assign in vvp) an assign event is created, which includes +the vvp_ipoint_t pointer to the functor input to receive the value, +as well as the value. These are distinct from propagation events because:

+
+
    +
  1. There is no functor that has as its output the value to be +assigned (this is how values get into the functor net in +the first place), and

  2. +
  3. This allows for behavioral code to create waveforms of +arbitrary length that feed into a variable. Verilog allows +this of non-blocking assignments, but not of gate outputs.

  4. +
+
+

The last type of event is the thread schedule event. This event simply +points to a thread to be executed. Threads are made up of a virtual +processor with a program counter and some private storage. Threads +can execute %assign instructions to create assignment events, and can +execute %set instructions to do blocking assignments. Threads can also +use %load to read the output of functors.

+

The core event scheduler takes these three kinds of events and calls +the right kind of code to cause things to happen in the design. If the +event is a propagate or assignment event, the network of functors is +tickled; if the event is a thread schedule, then a thread is run. The +implementation of the event queue is not important, but currently is +implemented as a skip list. That is, it is a sorted singly linked +list with skip pointers that skip over delta-time events.

+

The functor net and the threads are distinct. They communicate through +thread instructions %set, %assign, %waitfor and %load. So far as a thread +is concerned, the functor net is a blob of structure that it pokes and +prods via certain functor access instructions.

+
+
+

VVP Compilation And Execution

+

The vvp program operates in a few steps:

+
+
    +
  1. +
    Initialization

    Data structures are cleared to empty, and tables are +readied for compilation.

    +
    +
    +
  2. +
  3. +
    Compilation

    The input file is read and compiled. Symbol tables are +build up as needed, objects are allocated and linked +together.

    +
    +
    +
  4. +
  5. +
    Cleanup

    Symbol tables and other resources used only for +compilation are released to reduce the memory +footprint.

    +
    +
    +
  6. +
  7. +
    Simulation

    Event simulation is run.

    +
    +
    +
  8. +
+
+

The initialization step is performed by the compile_init() function in +compile.cc. This function in turn calls all the *_init() functions in +other parts of the source that need initialization for compile. All +the various sub-init functions are called <foo>_init().

+

Compilation is controlled by the parser, it parse.y. As the parser +reads and parses input, the compilation proceeds in the rules by +calling various compile_* functions. All these functions live in the +compile.cc file. Compilation calls other sections of the code as +needed.

+

When the parser completes compilation, compile_cleanup() is called to +finish the compilation process. Unresolved references are completed, +then all the symbol tables and other compile-time-only resources are +released. Once compile_cleanup() returns, there is no more use for the +parser for the function in compile.cc.

+

After cleanup, the simulation is started. This is done by executing +the schedule_simulate() function. This does any final setup and starts +the simulation running and the event queue running.

+
+
+

How To Get From There To Here

+

The vvp simulation engine is designed to be able to take as input a +compiled form of Verilog. That implies that there is a compiler that +compiles Verilog into a form that the vvp engine can read.

+
    +
  • Boolean logic gates

  • +
+

Gates like AND, OR and NAND are implemented simply and obviously by +functor statements. Any logic up to 4 inputs can be implemented with a +single functor. For example:

+
and gate (out, i1, i2, i3);
+
+
+

becomes:

+
gate    .functor and, i1, i2, i3;
+
+
+

Notice the first parameter of the .functor is the type. The type +includes a truth table that describes the output with a given +input. If the gate is wider than four inputs, then cascade +functors. For example:

+
and gate (out, i1, i2, i3, i4, i5, i6, i7, i8);
+
+
+

becomes:

+
gate.0  .functor and, i1, i2, i3, i4;
+gate.1  .functor and, i5, i6, i7, i8;
+gate    .functor and, gate.0, gate.1;
+
+
+
    +
  • reg and other variables

  • +
+

Reg and integer are cases of what Verilog calls variables. +Variables are, simply put, things that behavioral code can assign +to. These are not the same as nets, which include wires and the +like.

+

Each bit of a variable is created by a .var statement. For example:

+
reg a;
+
+
+

becomes:

+
a       .var "a", 0, 0;
+
+
+
    +
  • named events

  • +
+

Events in general are implemented as functors, but named events in +particular have no inputs and only the event output. The way to +generate code for these is like so:

+
a  .event "name";
+
+
+

This creates a functor and makes it into a mode-2 functor. Then the +trigger statement, “-> a”, cause a %set a, 0; statement be +generated. This is sufficient to trigger the event.

+
+
+

Automatically Allocated Scopes

+

If a .scope statement has a <type> of autofunction or autotask, the +scope is flagged as being an automatically allocated scope. The functor +for each variable or event declared in that scope is added to a list +of items that need to be automatically allocated for each dynamic +instance of that scope.

+

Before copying the input parameters of an automatic function or task +into the scope variables, a new scope instance needs to be allocated. +For function or task calls in procedural code, this is handled by the +%alloc instruction. For structural function calls, this is handled +by the phantom code generated by the .ufunc statement. In both cases, +VVP attempts to use a previously freed scope instance - only if none +are available is a new instance created.

+

After copying the result of an automatic function or the output +parameters of an automatic task, the scope instance can be freed. +For function or task calls in procedural code, this is handled by the +%free instruction. For structural function calls, this is handled +by the phantom code generated by the .ufunc statement. In both cases, +VVP adds the instance to a list of freed instances for that scope, +which allows the storage to be reused the next time a new instance +is required.

+

For each automatically allocated scope instance, VVP creates an array +of items, referred to as the scope context. Each item in this array is +a pointer to the allocated storage for holding the state of one scope +variable or event. The index into this array for any given variable +or event, referred to as the context index, is stored in the functor +associated with that variable or event.

+

Each VVP thread keeps track of its current write context and current +read context. For threads executing in a static scope, these are both +initialized to null values. For threads executing in an automatically +allocated scope, these are both initialized to refer to the context +allocated to that scope.

+

Before starting the copying of the input parameters of an automatic +function or task, the current write context of the caller thread is +set to the context allocated for that function/task call. After the +thread that executed the function/task body has been rejoined and +before starting the copying of the result or output parameters, the +current write context is reset to its previous value and the current +read context is set to the context allocated for the function/task +call. After finishing the copying of the result or output parameters, +the current read context is reset to its previous value.

+

When reading or writing the state of an automatically allocated +variable or event, the associated functor indirects through the +current read or write context of the running thread, using its +stored context index.

+
/*
+ * Copyright (c) 2001-2024 Stephen Williams (steve@icarus.com)
+ *
+ *    This source code is free software; you can redistribute it
+ *    and/or modify it in source code form 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/index.html b/developer/index.html new file mode 100644 index 0000000000..e0e532689b --- /dev/null +++ b/developer/index.html @@ -0,0 +1,130 @@ + + + + + + + + + Icarus Verilog Developer Support — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Icarus Verilog Developer Support

+

This section contains documents to help support developers who contribute to +Icarus Verilog.

+ +
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/regression_tests.html b/developer/regression_tests.html new file mode 100644 index 0000000000..46880feab3 --- /dev/null +++ b/developer/regression_tests.html @@ -0,0 +1,225 @@ + + + + + + + + + The Regression Test Suite — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

The Regression Test Suite

+

Icarus Verilog development includes a regression test suite that is included +along with the source. The “ivtest” directory contains the regression test +suite, and this suite is used by the github actions as continuous integration +to make sure the code is always going forward.

+

NOTE: There are scripts written in perl to run the regression tests, but they +are being gradually replaced with a newer set of scripts. It is the newer +method that is described here.

+
+

Test Descriptions

+

Regression tests are listed in the regress-vvp.list file. Each line lists the +name of the test and the path to the dest description. The list file is +therefore pretty simple, and all the description of the test is in the +description file:

+
macro_str_esc  vvp_tests/macro_str_esc.json
+
+
+

The “name” is a simple name, and the test-description-file is the path (relative +the ivtest directory) to the description file. A simple test description file +is a JSON file, like this:

+
{
+  "type"   : "normal",
+  "source" : "macro_str_esc.v",
+  "gold"   : "macro_str_esc"
+}
+
+
+

This description file contains all the information that the vvp_reg.py script +needs to run the regression test. The sections below describe the keys and +values in the description file dictionary.

+
+

source (required)

+

This specifies the name of the source file. The file is actually to be found +in the ivltests/ directory.

+
+
+

type (required)

+

This describes the kind of test to run. The valid values are:

+
    +
  • normal - Compile the source using the iverilog compiler vvp target, and if +that succeeds execute it using the vvp command. If there is no gold file +specified, then look for an output line with the “PASSED” string.

  • +
  • normal-vlog95 - This is similar to the normal case, but uses +the -tvlog95 target in a first pass to generate simplified verilog, then a +regular iverilog command with the -tvvp target to generate the actual +executable. This tests the -tvlog95 target.

  • +
  • NI - Mark the test as not implemented. The test will be skipped without +running or reporting an error.

  • +
  • CE - Compile, but expect the compiler to fail. This means the compiler +command process must return an error exit.

  • +
  • EF - Compile and run, but expect the run time to fail. This means the +run time program must return an error exit.

  • +
+
+
+

gold (optional)

+

If this is specified, it replaces the “Passed” condition with a comparison of +the output with a gold file. The argument is the name of the gold file set, +which will be found in the “gold/” directory. The name here is actually the +basename of the gold files, with separate actual gold files for the iverilog +and vvp stderr and stdout. For example, if a “normal” test includes a gold +file, then the program is compiled and run, and the outputs are compared with +the gold file to make sure it ran properly.

+

The way the regression suite works, there are 4 log files created for each +test:

+
    +
  • foo-iverilog-stdout.log

  • +
  • foo-iverilog-stderr.log

  • +
  • foo-vvp-stdout.log

  • +
  • foo-vvp-stderr.log

  • +
+

The “gold” value is the name of the gold file set. If the gold value is “foo”, +Then the actual gold files are called:

+
    +
  • gold/foo-iverilog-stdout.gold

  • +
  • gold/foo-iverilog-stderr.gold

  • +
  • gold/foo-vvp-stdout.gold

  • +
  • gold/foo/vvp-stderr.gold

  • +
+

If any of those files is empty, then the gold file doesn’t need to be +present at all. The log files and the gold files are compared byte for +byte, so if the output you are getting is correct, then copy the log to +the corresponding gold, and you’re done.

+

If the run type is “CE” or “RE”, then the gold files still work, and can +be used to check that the error message is correct. If the gold file setting +is present, the error return is required, and also the gold files must match.

+
+
+

iverilog-args (optional)

+

If this is specified, it is a list of strings that are passed as arguments to +the iverilog command line.

+
+
+

vvp-args (optional)

+

If this is specified, it is a list of strings that are passed as arguments to +the vvp command. These arguments go before the vvp input file that is to be +run.

+
+
+

vvp-args-extended (optional)

+

If this is specified, it is a lost of strings that are passed as arguments to +the vvp command. These are extended arguments, and are placed after the vvp +input file that is being run. This is where you place things like plusargs.

+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/developer/version_stamps.html b/developer/version_stamps.html new file mode 100644 index 0000000000..4c8fa31e8a --- /dev/null +++ b/developer/version_stamps.html @@ -0,0 +1,153 @@ + + + + + + + + + Files With Version Information — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Files With Version Information

+

These are the only files that have version information in them:

+
    +
  • version_base.h – This should be the 1 source for version info.

  • +
  • version_tag.h – Generated automatically with git tag information.

  • +
  • verilog.spec – Used to stamp RPM packages

  • +
+

When versions are changed, the above files need to be edited to account for +the new version information. The following used to have verion information in +them, but now their version information is generated:

+

The version_tag.h file is generated from git tag information using +the “make version” target, or automatically if the version_tag.h +file doesn’t exist at all. This implies that a “make version” is +something worth doing when you do a “git pull” or create commits.

+

The files below are now edited by the makefile and the version.exe program:

+
    +
  • iverilog-vpi.man – The .TH tag has a version string

  • +
  • driver/iverilog.man – The .TH tag has a version string

  • +
  • driver-vpi/res.rc – Used to build Windows version stamp

  • +
  • vvp/vvp.man – The .TH tag has a version string

  • +
+

This now includes version_base.h to get the version:

+
    +
  • vpi/vams_simparam.c – Hard coded result to simulatorVersion query

  • +
+

This is actually a test file list that is specific to a major version. +The regression test scripts query the version of the compiler to infer +that it must include this list of tests. For example, for version 12.x +of the compiler, the needs to be an ivltest/regress-v12.list file that +lists the tests that are specific to that version.

+
    +
  • ivltests/regress-XXX.list – Version specific regression tests

  • +
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/genindex.html b/genindex.html new file mode 100644 index 0000000000..00f798f0db --- /dev/null +++ b/genindex.html @@ -0,0 +1,107 @@ + + + + + + + + Index — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ + +

Index

+ +
+ +
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000000..4edf33db93 --- /dev/null +++ b/index.html @@ -0,0 +1,165 @@ + + + + + + + + + Icarus Verilog — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/objects.inv b/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..eb8afd00ad036bca09ef171d70a6d94754db8bc0 GIT binary patch literal 1365 zcmV-b1*-ZZAX9K?X>NERX>N99Zgg*Qc_4OWa&u{KZXhxWBOp+6Z)#;@bUGkOV_|Z2 zb0Ah_a%pUDX9^=AR%LQ?X>V>iAPOTORA^-&a%F8{X>Md?av*PJAarPHb0B7EY-J#6 zb0A}HZE$jBb8}^6Aa!$TZf78RY-wUH3V7O$n9XwAHW0_}dI}uvgR1c~?M!=9Y{}77 zPTAN|decB8L}3DgEC4cgPkoF&U!SCl4-)(U#9Sl_``_P!SYQDtBMo6?MZ_v6N>QF4 zrNTmy3`v#!nw2S9-k~fe`r)Dqh8}GrdUl>zB8=`!t^_^RiikzepOsQ#@fM*wtHZiq zefOGXWR>EqV$^*_NK>JO-s6n$l%Qn4yF*W9Rx=_e0VvPN>ou?uSl~lzLXX-sWi@Pt zl^Y6q6*^E_`Yy$ymgqnPWo3@mojDk1zTd6L(GPpHL@yTt*%JDrs3;re%eyt~2>FEx zFdLv#+9>-HXZXYjda>^7WQT6N=r$ORRmEH!kk|lUE?A+RMEm3^$l^pXDrfucWS05S z`D{y3U=_rwWyaVX)QE!PFil}WWxAq-kh>p$ez)Z1%zO#RU0OGrjc!99%g{`*esfdB zt1R>heiOzpCuJRB%5U_nW|>B1na{=nRw04sx~fW{&`lx;qXp%#@^8a&UMZveb$OwD zK3Y#}WBzFx&Y}F1>_Ne9ic9&NXo`4zqCJf7W4uZh(J}p!wnI}4Gu>| z6`>C`mc6BVq3DF^*D(AYKbwsQo)oG&BNaBcUw3MWdshkoCvI-z}zgA7Tpez=PJiBq_%nFHhEkJkXkfE@_Klr7~4G3 zD5pr>JVaJFN(7S!ChL8G2a*vkJw$pi%)L{9(@)t>I>KMFXp*$82mbI7N|P3ikPzgT zpQ2D>o%Z*?fBprh0N?0G5r(yXWb$mS3lMeIY6+`-m6k<;d3HRTI@m)7%zXt)@YJsC)xg!S!;rp?v^rL$0+|}1_xFG?qHMsi@ zJn8Mh?HP|Rzv&i-poV*NuW}@>ig3N91jZpM4eqR)&K!>PS53v&`6yNvjPQpswe)f6 z?==U#KWlsE3<+TFU=d(=YrB2+^!6U_qz$X8*gWbPyZdya50Ls^4cC~eJ2zTAw7`Kx zPY)_(9h&N6g~fhqTj7$cTOCgNv(p6RZEkb*+RxIELesC!QTYFgm}YR5=>J9G9H2DC z$FOg;AlnjOgQJ6R*J!=%+ra_2RX5dfa=93p{Bd;06;voVjKdn#*U}y&*8gVEc@2s8 X9JKC=6$Uw@N11=p+FRNG4s0TM+4GY% literal 0 HcmV?d00001 diff --git a/search.html b/search.html new file mode 100644 index 0000000000..5950735a07 --- /dev/null +++ b/search.html @@ -0,0 +1,126 @@ + + + + + + + + Search — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Search

+ + + + +

+ Searching for multiple words only shows matches that contain + all words. +

+ + +
+ + + +
+ + + +
+ +
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 0000000000..85979a3a22 --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({docnames:["developer/getting_started","developer/glossary","developer/guide/cadpli/cadpli","developer/guide/index","developer/guide/ivl/attributes","developer/guide/ivl/index","developer/guide/ivl/ivl_target","developer/guide/ivl/lpm","developer/guide/ivl/netlist","developer/guide/ivl/t-dll","developer/guide/misc/ieee1364-notes","developer/guide/misc/index","developer/guide/misc/swift","developer/guide/misc/xilinx-hint","developer/guide/tgt-vvp/tgt-vvp","developer/guide/vpi/index","developer/guide/vpi/va_math","developer/guide/vpi/vpi","developer/guide/vvp/debug","developer/guide/vvp/index","developer/guide/vvp/opcodes","developer/guide/vvp/vpi","developer/guide/vvp/vthread","developer/guide/vvp/vvp","developer/index","developer/regression_tests","developer/version_stamps","index","targets/index","targets/tgt-blif","targets/tgt-fpga","targets/tgt-null","targets/tgt-pal","targets/tgt-pcb","targets/tgt-sizer","targets/tgt-stub","targets/tgt-verilog","targets/tgt-vhdl","targets/tgt-vlog95","targets/tgt-vvp","usage/command_files","usage/command_line_flags","usage/getting_started","usage/gtkwave","usage/icarus_verilog_extensions","usage/icarus_verilog_quirks","usage/index","usage/installation","usage/ivlpp_flags","usage/reporting_issues","usage/simulation","usage/verilog_attributes","usage/vhdlpp_flags","usage/vpi","usage/vvp_debug","usage/vvp_flags","usage/vvp_library"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["developer/getting_started.rst","developer/glossary.rst","developer/guide/cadpli/cadpli.rst","developer/guide/index.rst","developer/guide/ivl/attributes.rst","developer/guide/ivl/index.rst","developer/guide/ivl/ivl_target.rst","developer/guide/ivl/lpm.rst","developer/guide/ivl/netlist.rst","developer/guide/ivl/t-dll.rst","developer/guide/misc/ieee1364-notes.rst","developer/guide/misc/index.rst","developer/guide/misc/swift.rst","developer/guide/misc/xilinx-hint.rst","developer/guide/tgt-vvp/tgt-vvp.rst","developer/guide/vpi/index.rst","developer/guide/vpi/va_math.rst","developer/guide/vpi/vpi.rst","developer/guide/vvp/debug.rst","developer/guide/vvp/index.rst","developer/guide/vvp/opcodes.rst","developer/guide/vvp/vpi.rst","developer/guide/vvp/vthread.rst","developer/guide/vvp/vvp.rst","developer/index.rst","developer/regression_tests.rst","developer/version_stamps.rst","index.rst","targets/index.rst","targets/tgt-blif.rst","targets/tgt-fpga.rst","targets/tgt-null.rst","targets/tgt-pal.rst","targets/tgt-pcb.rst","targets/tgt-sizer.rst","targets/tgt-stub.rst","targets/tgt-verilog.rst","targets/tgt-vhdl.rst","targets/tgt-vlog95.rst","targets/tgt-vvp.rst","usage/command_files.rst","usage/command_line_flags.rst","usage/getting_started.rst","usage/gtkwave.rst","usage/icarus_verilog_extensions.rst","usage/icarus_verilog_quirks.rst","usage/index.rst","usage/installation.rst","usage/ivlpp_flags.rst","usage/reporting_issues.rst","usage/simulation.rst","usage/verilog_attributes.rst","usage/vhdlpp_flags.rst","usage/vpi.rst","usage/vvp_debug.rst","usage/vvp_flags.rst","usage/vvp_library.rst"],objects:{},objnames:{},objtypes:{},terms:{"0":[0,4,6,8,9,10,13,16,20,22,23,30,35,37,39,41,42,43,44,45,47,48,50,53,54,55],"00":23,"01":[23,41],"01xz":20,"02":41,"02110":[16,20,21,22,23],"06":41,"0d":[42,43],"0x":23,"0x1000":20,"0x3fff":20,"0x4000":20,"0x5a":23,"0x7fff":20,"0xzz1":9,"1":[1,3,8,9,10,13,16,20,21,22,23,26,30,34,35,37,38,39,40,41,42,43,44,48,50,54],"10":[0,8,13,16,23,30,41,47,49,50,54],"100":[0,42,54],"100u":8,"103":[1,7],"11":[0,23,41,42,43],"119":39,"12":[26,41],"127":8,"128":8,"128bit":10,"13":[0,34,39,47],"1301":[16,20,21,22,23],"1364":44,"14":[10,13,34],"15":[10,23,50],"16":[10,20,22,41],"16bit":10,"17":[42,43],"17179869183":10,"18":50,"19":[13,50],"1995":[10,41],"1998":49,"1999":13,"19990814":13,"1a":50,"1e":8,"1e0":35,"1i":13,"1n":8,"1s":[40,54],"1x":23,"2":[0,1,3,10,13,16,20,21,22,23,30,34,35,38,39,40,41,53,54],"20":30,"200":30,"2000":[10,13],"20000120":13,"2001":[10,20,21,22,23,41],"2003":12,"2005":41,"2007":16,"2008":41,"2009":41,"2012":41,"2014":41,"20140619":51,"2015":41,"2016":[40,41],"2022":0,"2024":[12,16,20,21,22,23,49],"2190":0,"22":30,"23":44,"2300":13,"2412":0,"25":54,"250":54,"27":0,"29":[42,43],"2s":23,"2u":23,"3":[8,10,20,22,23,34,39,47,54],"31":[44,50],"32":[10,20,38,53],"32bit":[10,20],"332211":23,"35":50,"36":10,"4":[8,10,16,20,22,23,25,38,50],"4123":0,"5":[9,10,13,20,22,40,41,42,43,50],"50234":0,"51":[16,20,21,22,23,50],"512":23,"513":43,"53":0,"533928600":54,"59762":0,"5th":10,"6":[20,22,23,30,48,53],"6039":0,"64":[20,23,44,50,53],"6472":0,"64bit":[10,20,22,23],"64k":22,"66234":0,"7":[10,20,22,42,43,45],"7923":53,"8":[0,10,20,22,23,42,43,47,50],"81":50,"8477":53,"8489":53,"8bit":20,"9":[0,8,10,16,23,41,47,50],"95":[27,28],"96":35,"98":0,"abstract":[1,3,7,20],"boolean":[20,23],"break":[10,20,54],"byte":[20,23,25],"case":[8,10,14,17,18,20,21,22,23,25,30,37,38,40,41,44,47,49,50,52,53,55],"catch":54,"char":[23,53],"class":[3,20,23,30,41],"default":[0,20,33,37,38,39,40,41,42,43,44,45,47,50,55],"do":[0,1,6,7,8,10,20,23,26,40,41,42,43,47,50,53,55],"export":[2,17,40,47,53],"final":[0,3,6,7,8,9,20,23,38,47,50,54,55],"float":[20,23,41],"function":[2,3,6,7,8,9,10,17,20,37,38,39,41,50,54,55,56],"import":[0,13,23,34,40,42,47,52],"int":[6,20,23,29,53],"long":[10,12,21,23,29,40,41,47],"new":[0,3,6,20,22,26,28,39,40,41,44,47,49,50],"null":[20,23,27,28,53],"public":[13,16,20,21,22,23],"return":[6,8,9,10,16,20,21,23,25,41,44,48,50,55],"short":[23,40],"static":[23,50,53,56],"switch":[0,13,37,40,41,42,47,48,50,53],"throw":50,"transient":23,"true":[8,20,23,44,48,50],"try":[10,17,41,48,49,53],"var":[20,21,23,41],"void":[20,53],"while":[10,23,53,55],A:[0,1,3,7,8,10,15,20,21,22,23,25,29,38,39,40,41,42,48,50],AND:[8,10,20,23],AS:10,And:[3,42,54],As:[0,8,10,23,30,42],At:[8,42,43],BE:10,Be:[41,49],But:[8,10,30,45],By:[8,41,43],FOR:[16,20,21,22,23],For:[2,3,4,6,8,9,10,13,16,17,19,20,23,25,26,30,37,40,41,42,43,45,47,48,49,50,52,53,54],IF:20,IN:10,IS:[1,7],If:[0,4,6,8,10,14,20,21,22,23,25,30,39,40,41,42,43,44,45,47,48,49,50,53,54,55,56],In:[3,6,7,9,10,14,17,18,20,21,23,29,30,40,45,50,53,54,55],Is:[3,5,10],It:[0,1,3,4,6,7,8,10,16,17,20,21,23,25,30,34,35,38,40,41,44,50,54,55],NOT:[10,20,45],No:49,OF:10,OR:[20,23],Of:[20,50],On:49,One:[10,49,50],Or:[20,39],Such:10,THE:10,TO:10,That:[3,6,8,9,10,20,23,29,48,50,56],The:[0,1,2,4,7,8,9,10,12,13,16,17,18,20,21,22,24,26,27,40,41,42,43,44,45,47,48,49,51,52,53,54,55,56],Then:[0,18,20,23,25,42,43,50,52],There:[1,6,8,10,13,14,20,22,25,35,37,38,42,47,48,50,53,54],These:[1,4,6,8,10,18,20,22,23,25,26,40,41,42,45,47,48,50,53,55],To:[0,17,29,33,37,38,39,47,48,50,53,56],WITH:10,With:[2,10,24,27,30,34,35,39,40,46,53,54],_:23,_init:23,_ivl_:4,_ivl_schedule_push:4,_mode_:41,_will_:13,ab:[16,20],abc:29,abil:17,abl:[2,12,17,23,40,42,43,53],about:[8,10,21,23,30,34,40,41,49,50,53,54,55],abov:[0,8,10,13,20,23,26,40,41,44,45,47,48,53,54],absent:43,absolut:[16,20],acc2:50,acc:50,accept:[0,10,29,30],access:[0,6,8,9,16,17,20,21,22,23,50,51,52,56],accident:4,accomplish:23,accord:[10,17,20,50],account:[0,6,10,26],accumul:[8,50],accur:10,achiev:21,aclr:23,aco:16,acosh:16,acronym:1,across:[42,45],act:23,action:[25,56],activ:[2,17,20,23,41,43,53],actual:[0,6,10,20,21,23,25,26,41,42,47,48,53],ad:[0,10,20,21,23,28,41,55],adapt:8,add:[0,4,10,13,16,20,23,33,41,43,44,45,47,48,49,50,52,55],adder:10,addi:20,addit:[6,7,9,17,21,23,53],addr:[20,44],address:[8,10,20,22,23,49],adjust:[6,8],admittedli:13,advanc:[42,55],advantag:[8,50],affect:[10,20,21,23,41,50],after:[3,8,10,12,18,20,22,23,25,40,41,50,53,54],again:[10,49,50,53,55],against:[0,50],ahead:23,aid:[3,19,20,23,35,41,44],al:47,alanmi:29,algorithm:50,alia:[23,40],alias:23,all:[0,3,6,8,9,10,12,16,17,20,21,23,25,26,37,40,41,42,47,48,49,50,52,53,55,56],allianc:13,alliance_host:13,alloc:20,allow:[0,2,3,8,10,17,20,21,23,33,37,38,40,41,44,47,53,55],almost:[23,41,42,56],along:[12,16,18,20,21,22,23,25,42,48,50,53],alreadi:[0,10,20,43,49,50],also:[0,1,3,8,10,17,20,21,22,23,25,40,41,42,47,49,50,53,54,55,56],alter:[20,55],altern:[8,41,45],although:[8,10,40,41,50,56],altogeth:33,alwai:[0,4,8,10,13,23,25,34,38,40,41,42,43,44,47,49,50,51,53,54],am:[41,48],ambigu:[8,10],amongst:10,amount:[20,23,50],an:[0,1,2,3,4,6,8,9,10,13,18,20,21,22,23,25,26,30,33,37,38,41,42,44,45,47,48,49,50,51,53,54,55],anachron:41,analog:23,analys:53,analysi:3,analyz:[3,23,27,28],and2:50,ani:[4,6,8,10,16,17,20,21,22,23,25,29,30,34,37,40,41,42,43,44,45,47,48,49,50,53,54,55],annot:55,anoth:[8,10,20,23,41,42,50],ansi:38,anyedg:23,anyon:49,anywher:[10,40,51],api:[1,3,5,50,53],appar:10,appear:[8,10,21,23,41,48],append:[20,41],appendix:10,appl:47,appli:[8,10,20,51],applic:[2,8,17,53],appropri:[10,20,21,22,23,33,38,40,42,47,49,50],approv:0,ar:[0,1,3,4,6,7,8,9,10,12,13,14,16,17,18,20,21,22,23,25,26,28,29,30,33,35,37,38,39,40,41,42,43,44,45,47,48,49,50,51,52,53,54,55,56],arbitrari:[20,23,30,50],arbitrarili:10,arc:16,arch:30,architectur:[4,30],aren:1,arg:23,arguabl:10,argument:[2,3,16,20,23,25,38,39,40,42,43,50,53,54],argument_list:21,aris:56,arith:23,arithmet:[20,22,44],around:[0,14,20,23,54],arr:20,arrai:[3,8,17,20,21,32,37,38,41,50,53],arrang:[8,20,23],arriv:23,articl:53,artifact:8,ascii:9,aset:23,asic:29,asid:4,asin:16,asinh:16,ask:49,aspect:[6,8,23,53,55],assembl:[1,3,23,40],assert:[20,41],assign:[4,8,10,13,20,23,29,34,38,41,43,44,50],associ:[23,30,41],assum:[0,10,20,40,41,45,51,53],assumpt:10,async:[0,23],asynchron:23,atan2:16,atan:16,atanh:16,atom:23,attach:[4,14,23,30,33,51],attempt:[4,23],attent:[13,55],attribut:[3,5,7,13,27,30,46],august:13,authent:0,author:[0,53],autobegin:23,autoconf:[0,47],autofork:23,autofunct:23,automat:[8,16,20,21,26,38,41,42,53,55],autotask:23,avail:[0,13,20,21,23,30,39,40,41,42,43,44,47,55],avoid:[0,20,41,55],awai:[50,55],await:20,awar:23,aynchron:23,b000:54,b0:[10,23,34],b1:[23,54],b1zzx0:9,b:[0,8,10,20,23,47],back:[4,8,9,10,13,20,21,30,54,55],backend:[8,13,30],backward:44,bar:[10,52],base:[0,1,8,10,12,13,16,20,23,30,38,41,43,44,50,54,55],base_symbol:23,base_vers:47,baselin:44,basenam:[13,21,23,25],bash_profil:47,basic:[0,6,14,20,23,40,47,50],batch:50,batchmod:13,becaus:[3,7,8,10,20,21,23,30,42,43,44,50],becom:[10,23,29,30,40,41,42,50],been:[6,10,20,23,41,42,49],befor:[0,10,20,21,23,25,34,41,42,48,49,53,54,55],begin:[8,10,13,20,23,34,41,42,43,45,50,54,55],behav:[10,50],behavior:[4,6,7,10,20,23,34,41,44,48,50,55],behaviour:[37,41],being:[0,2,4,10,23,25,30,41,53],believ:[8,49],belong:[50,53],below:[0,3,18,23,25,26,43,47,54],bench:[4,42,43,50,51],berkelei:29,best:[6,13,23,47,49,50],better:[0,3,8,10,47,49],between:[10,40,50],beyond:50,bibl:10,big:10,bin:[13,39,47],binari:[3,20,47],bison:[0,3,47],bit2:50,bit:[9,10,13,20,22,23,29,30,38,41,44,47,50,53],bitgen:13,bitgen_flag:13,bitl:50,bitstor:53,bitwis:[8,20],black:33,blank:[40,48],blend:20,blif:[27,28],blink:34,blob:23,block:[3,8,10,20,23,38,41],blur:50,bnf:10,board:13,bodi:23,boiler:6,book:42,bool:[20,23,35,44],boot:12,boot_func:[2,53],bootstrap:[2,53],boston:[16,20,21,22,23],both:[6,8,10,20,23,41,44,55],bother:20,bottom:[3,53],bound:[21,41],boundari:[8,50],box:[33,40,43],branch:[20,22,23,41,47],breakpoint:20,brew:47,briefli:50,broken:[10,23],brought:8,brows:49,bsd:47,bu:[30,44],buf:[13,14,30],buffer:[13,30],bufg:13,bufz:14,bug:[0,49],build:[0,3,8,21,23,26,47],built:[0,8,16,18,20,23,47,54,56],builtin:3,bunch:20,bundl:[3,28],burden:[6,8],buri:13,button:[0,49],bx:[10,20,23,41],bz:[23,41],c1:[13,42,43],c3:13,c4:13,c:[0,1,3,6,8,10,16,20,21,22,23,26,40,41,42,47,49,50,53,54,56],ca:41,cadenc:[3,10,44],cadpli:[2,3,12,53],calcul:[8,9,10,20,23,41,50],call:[1,3,8,9,17,20,25,35,38,39,40,41,42,43,45,50,53,54],calle:23,caller:[20,23],callf:20,calltf:53,can:[0,2,3,4,6,7,8,10,12,13,16,18,20,21,22,23,25,28,29,30,33,34,38,39,40,41,42,43,44,45,47,48,49,50,52,53,54,55,56],cancel:20,candid:[42,50],cannot:[4,8,10,16,20,21,23,37,53],canon:[20,23],capabl:12,care:[3,20,23,43],cari:16,carri:[8,21,23,53],cascad:23,casex:20,casez:20,cassign:[20,23],cast2:20,cast:20,cat:13,categori:49,caught:21,caus:[0,2,4,6,10,20,23,30,31,40,41,42,43,47,48,49,50,53],cc:[0,3,23],cclk:13,cd:[0,13,47,54],ce:[23,25],ceil:16,cell:[23,30,51],cellref:30,celltyp:23,center:0,certain:[8,22,23,33,41,44,55],certainli:42,cf:50,chanc:[20,21],chang:[8,10,17,20,21,23,26,40,41,47,48,50,55],chapter:[20,42,45,50,53],charact:[9,10,18,20,23,30,40,41,42,45,48,50,54,55],characterist:49,check:[0,3,6,8,20,23,25,41,47,49,50,53],checkout:[0,47],checkpoint:10,child:[20,23],children:[8,20,23],choos:[10,12,23,30,41,42,43,50],chosen:55,chunk:20,claim:[10,49],clarif:10,clean:55,cleanup:[0,23,47],clear:[10,20,23,50],clearli:[10,42,50],click:[43,49],clk:[10,13,23,42,43,50,54],clock:[10,13,20,23,30,34,42,43,54],clone:[0,47],close:[1,7,49],closest:[10,20],clr:23,cmdfile:41,cmp:[20,23],cmpi:20,co:16,cobj:20,cobject:20,code:[0,1,3,4,6,7,8,9,10,12,17,20,21,22,23,25,26,27,28,41,42,45,47,49,50,51,52,53,54,55,56],collect:[9,17,23,50,53],colon:48,column:[10,23],com:[0,13,16,20,21,22,23,47],comb:23,combin:[4,8,10,13,20,23,40,41,42,50,53],combinatori:23,come:[0,8,10,12,20,23,50],comma:[4,23],command:[0,3,6,9,12,13,16,17,20,23,25,27,28,29,30,33,34,35,39,42,43,45,46,47,48,49,53,54],commandfil:42,comment:[23,38,48,49,53],commentari:23,commerci:10,commit:[0,26],common:[6,8,10,20,23,41,42,47,50,53,54],commonli:[0,39,41],commun:[23,56],compact:[20,43],compar:[20,25,44],comparison:[8,10,20,22,23,25,44],compat:[0,3,12,44,47],compil:[2,4,10,12,20,21,25,26,35,40,41,42,43,44,45,48,49,51,55],compile_:23,compile_cleanup:23,compile_init:23,compiletf:[21,53],compin:41,complement:23,complet:[0,8,9,10,20,23,29,30,40,49,50,53],complex:[3,6,8,23,42,48],complianc:41,compliant:[38,41],complic:[42,53],compon:[8,23,41],compound:8,compress:0,comput:[10,20],concat:[20,23],concaten:[9,10,20],concati:20,concept:[21,23,44],conceptu:3,concern:[10,23],concis:40,condit:[8,20,23,25,48,50],conf:6,config:[41,47,52],configr:13,configur:[6,50,56],conflict:[0,10],confus:[10,23,41],connect:[2,6,8,10,13,23,30,38,41,44,53],consid:[4,10,20,41,49,50,54],consist:[23,44],constant:[8,9,10,20,22,23,35,37,38,41,50],constrain:[10,20,23,50],constraint:[1,7],construct:[7,8,13,21,23,33,38],cont:54,contain:[0,3,6,8,10,17,20,21,22,23,24,25,29,30,33,34,35,37,38,39,40,41,42,45,46,47,48,50,52,53],content:[8,20,40,48,50],context:[8,20,23,38,54],contigu:23,continu:[0,8,20,23,25,29,38,40,41,44,50,54],contract:10,contradictori:10,contribut:[3,24,27,41,49],control:[8,10,16,20,23,30,33,40,41,42,47,48,50,54,55],conveni:[23,41,42,48,50,53],convent:[3,10,23,40,42],convention:10,convers:[20,49],convert:[20,29,44],cope:8,copi:[16,20,21,22,23,25,40,56],copyright:[12,16,20,21,22,23,41,48,49],core:[6,8,9,17,23,50,53],corner:[0,6],correct:[0,6,10,23,25,47,49],correctli:[20,23,38,41],correspond:[20,23,25,37,48],cosh:16,cosin:16,cost:55,could:[50,54],couldn:13,count:[0,9,20,23,48],counter:[22,23,42,43,48,50],counter_tb:[42,43],coupl:[0,54],cours:[6,20,50],cover:[13,44,49],coverag:10,cprop:6,crc:13,creat:[0,3,8,10,17,20,21,22,23,25,26,30,33,39,42,45,47,50,55],creation:[3,23,41,50],cross:[8,23,47],csh:13,cumbersom:42,current:[0,3,8,20,21,23,29,30,32,36,38,40,41,44,45,47,48,50,53,54],custom:[1,54],cvt:20,cygcari:16,cygwin:47,d:[0,13,16,20,23,40,41,48,50,52],dangl:41,dar:20,darrai:20,data:[8,20,23,45],databas:[21,49],datafil:45,date:[0,40,41],datum:23,de:[6,20],deactiv:[20,23],dead:[10,50],deal:[8,50],deassert:23,deassign:[20,23,43],debug:[0,3,17,19,20,35,41,44,52,54,55],debugg:20,decai:23,decid:[10,23],decim:[10,16,20,23,50],decis:10,declar:[8,9,10,13,20,21,23,30,33,37,40,41,44,52,53],decor:[3,41],dedic:13,def:23,defin:[0,1,3,4,6,9,10,20,21,23,30,40,41,47,48,50,53,55,56],definit:[6,8,10,20,21,23,30,40,41,50,51,53],defparam:[3,8,40,41],defparm:3,delai:[8,20,39,41],delay_or_event_control:10,delayx:20,delet:[8,20],delta:[0,23],demonstr:[6,10,40,49,50,53],dep:0,depend:[6,8,10,23,30,41,43,56],deprec:[3,41],depth:37,dereferenc:37,deriv:49,descend:[51,54],describ:[0,1,3,6,8,18,20,21,23,25,33,40,42,47,48,50,51,55],descript:[1,7,8,20,23,33,40,49,50,51],deserv:23,design:[1,3,6,7,8,9,10,12,13,14,21,23,28,29,30,33,35,37,40,41,42,43,44,50,51,53,55,56],design_dump:0,desir:[8,21,23,30,50,53],dest:25,destin:[0,20,23,50],destructor:8,detach:20,detail:[3,9,16,18,19,20,21,23,30,33,41,49,50,54],detect:[4,20,23,35,41,44],determin:[8,20,41,53,55],devel:[16,39],develop:[0,13,16,25,27,47,49,50,53,55],deviat:37,devic:[1,7,8,14,23,38,50],dhave_config_h:0,dialog:40,diarrhea:13,dictionari:25,did:39,differ:[6,9,10,20,21,23,30,40,41,42,44,45,50,56],difficult:[18,50],digit:23,dimens:[10,21,23,41],diod:23,dir:[40,48],direct:[3,8,10,21,23,30,39,40,41,50],directli:[3,18,20,39,41,50],directori:[0,3,12,13,16,17,25,40,41,45,47,48,50,52,53,55],dirti:39,disabl:[13,20,23,37,41,55],disallow:10,disciplin:0,disconnect:[8,20],discov:8,displai:[10,20,23,35,38,39,42,43,50,52,54,55],disput:10,distinct:[20,23],distinguish:23,distribut:[6,12,16,17,20,21,22,23,41,43,47],div:[20,23],divid:[3,20,50],divis:[20,37],dkei:41,dll:[6,9,53],dname:48,document:[0,3,4,9,10,12,17,22,24,27,40,45,46,49,56],doe:[3,6,7,8,10,12,20,21,23,30,33,34,38,40,41,48,50,51],doesn:[10,13,23,25,26,29,30,41,55],domain:[13,44],don:[10,13,17,20,45,47,49,53],done:[0,13,21,23,25,34,47,53,54],doneact:13,donepin:13,doolittl:[13,16],doubl:[23,48],doubt:10,down:[3,10,20,23,29,49],download:[0,47],downstream:30,dozen:42,draft:10,drag:43,drive0:23,drive1:23,drive:[8,23],driven:[37,44],driver:[0,3,14,23,26,30,41,44],drop:[20,38,54],dsn:43,dst:[20,23],due:[23,50],dump:[10,18,35,43,55],dumpfil:[43,55],dumpoff:10,dumpvar:[43,55],dup:20,duplic:20,dure:[4,6,8,10,41,42,50,55],dut1:50,dut2:50,dut:50,dynam:[2,6,9,20,23,53,56],e:[0,8,9,10,16,20,23,38,41,47,50,51],each:[6,8,10,14,20,21,22,23,25,30,37,38,40,41,45,50,53,56],earli:10,earlier:[23,41],eas:[8,48],easi:[0,50],easier:[8,53],easiest:[0,47],easili:[1,7,8,10,23],echo:47,ed:20,eda:50,edf:30,edg:[10,23],edif2ngd:30,edit:[26,40,49,50],editor:42,editori:49,edu:29,eec:29,eeq:[20,23],ef:25,effect:[4,8,10,20,21,23,41,42,55],effici:[3,10,20,50],ei:[1,7],either:[8,16,20,21,22,23,44,50],elab_scop:3,elabor:[3,6,8,9,28,29,35,42,53],elaborate_root_scope_t:3,elaborate_scop:3,element:[8,20,33,40],elid:51,elimin:[20,41,50],els:[30,34,42,43,50],elsewher:[3,10,23],email:47,embed:4,emerg:40,emit:[3,8,20,23,29,30,37,38],emphasi:10,empti:[6,10,23,25,52,53],emul:3,en:23,enabl:[0,13,18,23,41,43,47,48,52,56],enclos:41,encod:[8,20,23],encount:52,encourag:[0,49],end:[0,4,8,9,10,13,16,20,23,30,34,35,37,39,40,42,43,45,50,53,54,56],endfunct:10,endmodul:[10,30,34,35,39,42,43,50,53,54],endtask:50,engin:[0,3,19,20,21,39,42,50,54,55],enough:[0,1,7,20,23,40,47,49,50],enqueu:3,enter:[33,41,47,50],entir:[10,20,21,41,50,53],entiti:[37,52],enumer:[0,6],environ:[3,8,12,17,18,40,42,47,53],eq:[20,23],equal:[10,20,23],equival:[10,13,20,39,50],eras:8,erron:[23,50],error:[0,4,10,20,21,23,25,30,40,41,44,47,48,49,50],escap:53,especi:[1,7,10,53,55],essenti:[2,53],et:47,etc:[0,3,4,7,10,14,20,23,38,47,51,53],eval:41,eval_tre:41,evalu:[3,8,9,41],evaluate_paramet:3,evctl:20,even:[3,7,8,10,16,20,21,22,23,30,37,38,40,41,42,45,50,51,53],event:[8,10,20,54],event_control:10,event_express:41,eventu:[23,47],ever:10,everi:[6,10,20,23,48,50],everyon:49,everyth:[8,43,47],ex:[26,47],exact:3,exactli:[6,10,20,23,30,38,40,41,44,48,50,53],examin:8,exampl:[0,2,4,6,8,9,10,12,17,20,22,23,25,26,30,33,34,35,37,39,41,42,44,45,47,48,49,50,51,52,54],except:[10,16,20,23,37,40,48,49],excess:[1,7],exclus:[20,41],execut:[0,3,8,10,12,19,22,25,39,41,42,50,53,54,55],exercis:50,exhaust:45,exist:[10,20,23,26,41,45,48,49],exit:[25,48],exp:[16,20,30],expand:[8,10,23],expect:[6,10,17,20,22,23,25,40,41,49,50,56],experi:[13,20],expir:23,explain:[49,53],explicit:[10,29,30,41,53],explicitli:[8,10,20,33,41,50],explod:29,exponenti:16,expos:8,expr:[10,41],expr_width:8,express:[3,10,20,21,23,37,38,41,44,50,53],extend:[2,20,23,40,41,43,50,53],extens:[0,20,23,27,38,40,41,46],extern:[3,8,28,30],extra:[0,23,30,41,47],extract:[13,20],f:[13,20,23,48],fab:20,face:44,fact:[6,8,10,23,50],fail:[10,20,23,25],failur:[20,50],fairli:[0,40],fall:[23,49],fals:[8,41,44,48],famili:30,familiar:[41,44],far:[10,23,49,50],fast:13,faster:[20,43],fat:40,fatal:41,fault:10,fdll:9,featur:[0,41,42,44,50],februari:13,fed:14,feed:[14,23],feedback:0,feel:10,fetch:22,few:[0,23,38,42,47,49,50],fewer:20,field:33,fiendishli:18,fifth:[16,20,21,22,23],figur:[8,23,42],file:[0,3,4,8,9,10,12,16,17,18,20,21,22,23,24,25,27,29,30,33,37,38,39,41,42,43,45,46,47,52,53,55,56],file_lin:20,file_list:42,file_nam:39,filenam:[40,48],fill:8,filter:10,find:[3,4,6,9,10,16,20,39,41,47,49,50,53],fine:10,finish:[3,10,20,23,38,42,43,50,54],first:[0,8,10,12,14,20,21,23,25,39,41,42,43,45,47,48,50,53,54,55],fit:[13,16,20,21,22,23],fix:[0,10,20,21,22,23,38,49],flabel:23,flag1:20,flag2:20,flag:[2,6,8,9,10,22,23,27,28,30,34,40,42,43,44,46,47,50,53,54],flag_get:20,flag_inv:20,flag_mov:20,flag_or:20,flag_set:20,flatten:[8,29],flavor:[23,47],flex:[0,3,47],flexibl:50,flip:[4,7,13,23,34],floor:[16,20,21,22,23],flop:[4,7,13,23,34],flow:20,flush:54,fncf:13,fnodangl:13,fold:49,follow:[0,4,6,10,13,20,23,26,30,37,38,39,40,47,48,50,53,54],foo:[0,10,17,23,25,30,33,41,43,44,48,49,52,53,54,55],foo_clock:54,footprint:23,forc:[20,37,41],forget:47,fork:[20,23,37],form:[1,3,8,9,10,14,20,21,22,23,38,40,41,42,48,50,53],format:[2,3,4,5,6,17,20,27,29,30,33,41,42,43,46,48,50,53,55],forth:20,forward:[10,25,40],found:[0,13,25,37,41,45,47,49,50],foundat:[13,16,20,21,22,23],four:23,fpga:[13,27,28],fpic:[6,53],fraction:10,franklin:[16,20,21,22,23],free:[0,16,20,21,22,23,47],freed:23,freeli:[8,54],freshli:53,friend:55,friendli:[10,49],from:[0,2,3,8,9,10,12,14,17,18,20,21,22,26,30,33,37,38,40,41,42,44,45,48,49,50,53,54,55,56],front:[20,52],fst:43,fsynth:13,ftp:13,full:[14,20,21,50],full_nam:14,fulli:[8,9,10,41,50],functor:[3,6,7,8,20,21],further:[4,8,10,23,30,50],furthermor:10,fuss:53,futur:20,fxnfio:13,g2001:41,g8cb2e1a05:39,g:[0,13,20,38,41,47],gack:13,gain:[6,23,42],gate:[8,10,13,14,23,29,30,34,38,50],gbuf:30,gcc:[0,6,47,53],ge:23,gener:[0,1,3,4,6,7,8,9,10,12,16,20,21,22,25,26,27,28,34,40,42,43,44,47,50,53,54,55],get:[2,3,6,8,10,12,17,20,21,24,25,26,27,30,41,46,47,49,50,52,53,54],get_precis:8,getv:20,git:[0,3,26,41,47,49],github:[0,16,25,43,47,49],give:[3,6,10,20,21,23,30,40,47,48,50],given:[0,8,10,13,20,21,22,23,30,33,40,41,42,47,50,55],global:[3,8,13,23,45,47],glossari:[24,27],gmake:13,gno:[41,44],gnu:[0,16,20,21,22,23,33,47,53],go:[0,6,9,20,23,25,42,49,50,54,55],goal:38,goe:[23,47,55],gone:50,good:[10,13],goof:10,gotten:47,gov:13,gperf:[0,3,47],gpl:49,gradual:25,great:[50,54],greater:[20,23,38],green:49,grief:49,gross:3,group:42,grow:50,gsrinact:13,gt:23,gtk:43,gtkwave:[27,46,55],guess2:50,guess:[8,50],gui:13,guid:[0,24,27,46],guidanc:10,gxtype:44,gz:13,h0_00_00_00_01:10,h1:10,h1_00_00_00_00:10,h3_ffff_ffff:10,h5_00_00_00_00:10,h:[3,6,8,9,23,26,41,42,43,53,56],ha:[2,3,6,8,10,13,14,20,21,23,26,30,40,41,42,49,50,53,54],had:13,hand:50,handbook:53,handi:8,handl:[3,6,8,9,10,20,21,23,41,48,53],happen:[4,6,10,12,23,31,42],hard:26,hardli:[2,53],hardwar:[1,7,50],have:[0,1,6,8,10,13,16,20,21,22,23,26,33,37,40,41,42,44,47,48,49,50,53],haven:13,he:13,head:[0,10,20,47],header:[3,6,9,16,40,41,52,53,56],hear:49,heavi:3,held:23,hello:[23,35,39,42,53,54],hello_calltf:53,hello_compiletf:53,hello_regist:53,hello_world:[35,39],help:[3,4,6,8,20,24,40,41,46,49,50,53,54],henc:41,here:[0,1,3,4,9,10,12,13,20,25,38,41,42,43,47,53,55],hex:50,hi:[10,16,40],hierarch:[8,10,14,23,37,40,50],hierarchi:[20,21,37,42,50,54],high:[20,23],hint:[3,10,11],hold:[4,8,9,10,20,21,22,23,40,41,42,50],homebrew:47,hope:[16,20,21,22,23],hopefulli:8,host:[0,13,47,56],how:[3,6,10,20,42,50],howev:[0,8,10,12,21,23,30,43,47,48,49,50],howto:13,hp:20,html:13,http:[13,16,29,47],human:[23,50],hundr:[40,42,49],hyperbol:16,hypot:16,hypotenus:16,hypothet:40,i1:23,i2:23,i3:23,i4:23,i5:23,i6:23,i7:23,i8:23,i:[0,1,8,9,10,12,13,16,20,23,30,40,41,48,49,50,51],ibuf:30,icaru:[1,2,3,5,6,7,9,10,12,13,16,20,21,22,23,25,29,30,32,35,36,37,38,39,41,43,48,49,51,52,53,55],id:0,idea:[8,20,45,50],ideal:[1,7,10],ident:[12,20],identif:23,identifi:[20,21,23,42,50],idiom:20,idx:[10,20,23],ieee1364:[1,3,11,41],ieee1800:41,ieee754:10,ieee:[41,44],ifdef:[3,41,50],ifndef:50,ignor:[10,23,40,41,48,51,53],ii:30,ilibmisc:0,illeg:10,imag:50,imagin:3,imm:20,immedi:[20,22],impact:3,implement:[1,3,9,10,16,17,20,21,25,30,45,48,50,53],impli:[8,16,20,21,22,23,26,44],implic:[10,41],implicit:[10,20,23,41],implicitli:[0,10,40,41,44,47,53],impos:[8,10,42,44,56],imposs:8,impract:53,improv:[10,20],in0:30,in1:30,in2:30,inc:[16,20,21,22,23],incdir:[40,50],includ:[0,3,6,8,10,12,13,16,17,20,21,22,23,25,26,30,32,36,40,41,42,43,44,47,49,50,53,54,55,56],inclus:[0,48,49,50],incomplet:41,inconsist:41,inconveni:50,incorrect:49,increas:[9,49],increment:22,inde:8,indent:38,independ:[20,23,30,40,49,50],indeterninit:41,index:[6,8,9,20,27,38,39,41],indic:[20,21,23,33],indirect:23,indirectli:41,individu:[0,3,23,50],inf:[16,20],infect:10,infer:[4,26],infinit:[41,54],infloop:41,info:[26,49,55],inform:[0,3,8,13,18,20,21,23,24,25,27,38,40,41,47,48,49,50,53,55],infrastructur:12,inherit:[8,41],init:23,initi:[3,4,8,10,12,23,35,39,42,43,45,50,52,53,54],inlin:8,inout:38,input:[3,6,8,10,13,14,20,21,22,23,25,30,33,34,35,38,41,42,43,48,55],insensit:40,insert:50,insid:41,insist:49,instal:[0,2,3,12,27,40,41,46,53],instanc:[3,8,10,20,23,33,38,41,45,50,56],instanti:[3,8,10,23,29,33,38,41,42,50],instead:[0,2,3,8,10,20,23,30,34,37,41,45,48,50,53,55],instruct:[0,3,12,19,21,22,39,47,49,53],instrument:54,int64_t:23,integ:[4,8,9,10,20,22,23,38,41,50],integr:[0,2,25,50,53],intend:[3,4,10,12,20,23,29,42,50],intent:[10,20],interact:[10,13,20,23,27,39,46,55,56],interest:[12,13,42,55],interfac:[1,2,3,12,17,21,30,53,56],interior:4,intermingl:3,intern:[1,3,4,6,29,30,44,50],interpret:[2,7,8,10,23,33,42,48,50,53],interrupt:54,inv:20,invalid:20,invers:23,invert:20,invoc:[3,54],invok:[2,6,9,12,17,21,23,29,31,33,34,37,38,42,49,53,54],io:41,irrelev:10,isbn:53,issu:[27,46,53],isymbol:23,item:[3,10,20,23,50,54],iter:[8,50],its:[4,8,10,14,20,23,41,50,53,56],itself:[3,4,6,8,10,12,20,23,35,43,50],iverilog:[0,2,3,6,16,26,27,29,30,33,34,35,37,38,39,40,42,43,46,47,49,50,53],iverilog_dump:55,iverilog_vpi_module_path:53,ivl:[3,6,9,27,39,46,49],ivl_:[4,51],ivl_black_box:33,ivl_combin:4,ivl_delay_select:39,ivl_design_t:6,ivl_do_not_elid:51,ivl_ex_concat:9,ivl_ex_numb:9,ivl_expr_bit:9,ivl_expr_parm:9,ivl_lpm_data2:6,ivl_lpm_data2_width:6,ivl_lpm_defin:6,ivl_lpm_q:6,ivl_lpm_siz:6,ivl_lpm_t:6,ivl_lpm_typ:6,ivl_lpm_type_t:6,ivl_lpm_ufunc:6,ivl_lpm_width:6,ivl_nexus_t:14,ivl_scope_t:6,ivl_synthesis_cel:[4,51],ivl_synthesis_off:[4,51],ivl_synthesis_on:4,ivl_target:[3,5,9],ivl_vers:39,ivlpp:[3,27,46],ivltest:[25,26],ivtest:[0,25],ix:[20,22],jedec:32,jmp:[20,23],job:[23,53],join:[20,23,37],join_ani:20,join_non:20,json:25,judici:40,jump:[17,20],just:[0,1,10,16,20,38,40,41,47,50,52,53],justif:10,justifi:[10,23],keep:[8,20,23,45,48,50,53],kei:[0,25,41,48,49],kept:3,keyword:[1,3,23,41,44],kick:55,kind:[8,9,23,25,54],know:[2,8,20,21,23,30,45,50,53,54],knowledg:[0,50,53],known:[1,9,45,50],l:[8,10,13,20,23,38,40,41,48,52,53,55],l_:14,la:[23,54],label:[18,20,21,49],lack:50,languag:[1,6,10,23,41,44,50],larg:[3,10,40,41,50],larger:[20,42,50,56],larri:[13,16],last:[6,20,21,23,41,53],latch:4,later:[0,16,20,21,22,23,41,42,47,49,50,51],latest:[0,47,49],latter:[2,45,48,53,54],law:10,layout:33,lbl:13,lca:13,lead:[20,30,40,41,48,53],leak:[0,47],learn:[42,49],least:[9,10,20,21,23,41],leav:[8,10,20],left:[6,9,10,20,23,43,53,55],legal:[10,49],legitim:53,length:[10,21,23,41,50],less:[10,20,21,23],lest:23,let:[6,30,42,45,53],letter:10,level:[10,37,40,41,48,54],lex:[3,47],lexic:[3,23],lexor:[3,47],lexor_keyword:[0,3,47],lib:[6,12,39,52],libdir:[12,40,41,52],libext:40,librari:[1,2,3,7,15,17,27,30,40,41,43,46,47,53],libverius:3,libvpi:53,libvvp:[47,56],licens:[20,21,22,23,49],lift:3,like:[0,6,8,10,12,13,16,17,20,21,23,25,30,33,40,42,47,49,50,52,53,54,55],limit:[10,13,16,20,23,44,50],line:[3,6,8,9,12,16,18,20,23,25,27,28,30,33,38,39,40,42,46,47,49,50,53,54],lineno:23,link:[2,6,9,12,17,23,47,49,53],linker:53,linux:[2,6,13,42,43,53],list:[3,4,8,10,16,17,20,21,23,25,26,30,38,40,41,42,44,45,48,49,50,54],liter:[8,20,54],littl:10,live:23,ll:[10,20],lm_:12,lm_model:12,lmc_home:12,lmtv:12,ln:16,load:[0,2,3,6,12,17,20,23,39,41,50,53,54,55,56],loadabl:[2,3,5,53],loader:[9,53],loadi:20,loadpli1:[2,53],loc:30,local:[0,8,23,39,41,47],locat:[4,8,12,16,17,20,23,30,40,41,45,50,53],log10:16,log:[16,18,25,34,55],logarithm:16,logfil:55,logic:[4,8,10,13,14,20,29,30,32,34,35,38,41,44,50],longer:41,look:[2,3,10,13,23,25,38,41,48,49,50,52,53,54,55],lookup:[23,50],loop:[10,41,54],loop_stat:10,lose:13,loss:41,lossless:41,lost:[8,20,23,25],lot:[21,40,41,42,49,50],low:20,lower:52,lowercas:40,lpm:[1,3,5,30],lpm_ram_dq:8,lrdoolittl:13,lrm:[1,51],ls:54,lsb:[20,21,22,23],lt:20,luck:13,lvpi:53,lxt2:55,lxt2format:55,lxt:43,m:[2,16,23,41,50,53,54,55],m_1_pi:16,m_2_pi:16,m_2_sqrtpi:16,m_e:16,m_ln10:16,m_ln2:16,m_log10:16,m_log2:16,m_pi:16,m_pi_2:16,m_pi_4:16,m_sqrt1_2:16,m_sqrt2:16,m_two_pi:16,ma:[16,20,21,22,23],mac:47,machin:[1,23,40],macro:[30,41,48],macro_str_esc:25,macropreprocessor:50,made:[10,13,23,40,41,44],magic:21,mai:[0,3,4,8,10,12,13,20,23,29,30,33,38,40,41,42,44,47,48,49,50,51,53,54,56],main:[0,3,30,38,39,40,42,49,50,53,54],maintain:[3,44],major:[1,3,10,23,26,38,40,41],make:[0,4,6,8,10,13,20,21,23,25,26,30,40,42,43,47,48,53,56],make_root_scop:3,makefil:[13,26,47],man:[26,41],manag:[0,8,20,23,42,47],mangl:30,mani:[0,8,17,20,22,23,41,42,47,48,50,53],manipul:[8,20,22],manner:20,mant:20,mantissa:20,manual:[1,40,54],manufactur:23,map:[13,23,30],mark:[4,20,25,30,41,53],master:[0,41,47],match:[10,20,23,25,41,50,53],materi:[49,53],math:[3,15],matter:[8,10,23,50,53],max:[16,20,39,41],maximum:16,mcadpli:[2,12,53],mci:55,md:0,me:9,mean:[1,6,8,10,12,17,20,22,23,25,30,40,41,48,50,53],meaning:48,meaningless:23,meant:40,medium:42,meet:50,mem:45,memori:[0,20,23,45,47],mention:[21,23,50],merchant:[16,20,21,22,23],merg:[0,47],messag:[4,10,17,18,20,23,25,37,41,48,50,52,55],method:[0,3,8,9,20,21,25,42,50,53,54],mhello:53,mib:0,micro:50,microux:13,might:[1,10,23,30,41,49],mileag:13,mimic:50,min:[16,20,39,41],mind:[10,20],mingw32:47,mingw64:47,mingw:47,minim:21,minimalist:21,minimum:[16,53],minor:49,miracul:21,mirror:10,miscellan:3,miss:[21,41,45,50],mitig:56,mittra:53,mix:44,mkdir:0,mod:[20,23],mode:[23,27,41,46,55,56],model:[3,4,11,29,42,50],modeltech:10,moder:42,modifi:[16,20,21,22,23,50],modpath:23,modul:[1,3,4,7,8,10,12,15,16,27,29,30,33,34,35,37,38,39,40,41,42,43,44,51,54,55],module_item:10,module_item_declar:10,modulu:[20,38],monitor:[42,43],more:[0,3,6,8,9,10,16,20,21,22,23,30,37,40,41,42,48,49,50,53,55],mosi:6,most:[0,3,6,9,10,13,16,20,23,30,38,39,42,43,47,53,54],mostli:[23,48,53,56],mov:20,move:[23,30],msampl:53,msb:[20,21,23,38],msys2:47,much:[20,23,42],mul:20,muli:20,mult:23,multi:[40,42],multipl:[8,14,20,23,37,38,40,41,42,44,48,50,55,56],multipli:20,mung:40,must:[3,6,10,16,20,21,23,25,26,29,37,41,42,48,49,50,53],mux:34,muxr:20,muxz:23,mv:0,my:[0,10,13,17,47],my_boot:[2,53],my_buf:30,my_design:[37,38,42],my_design_95:38,my_gbuf:30,n:[20,23,37,38,39,53],name:[0,3,6,8,9,10,13,16,17,20,21,23,25,29,30,33,38,39,41,42,43,47,48,50,52,53,54,55,56],nan:[10,16,20],nand:[20,23],nanosecond:23,narrow:23,nativ:47,natur:[16,50],nb:20,nc:[2,10,53],ncd:[13,30],ncf:13,ncverilog:12,ne:[20,23],nearest:10,necessari:[10,20,23,29,42],necessarili:[20,23,30],nee:23,need:[0,3,4,6,7,8,9,10,12,16,17,20,21,22,23,25,26,30,38,41,42,47,48,49,50,53,55],neg:[10,23,38],negat:10,negedg:23,nest:[8,40,48],net8:23,net:[8,10,13,14,20,33,38,41,44,50,54],netassignmem_:8,netcondit:8,netememori:8,netexpr:8,netlist:[3,5,6,23,30,33,37,38,50],netmemori:8,netobj:8,netramdq:8,netscop:8,network:[6,23],neutral:[1,7],never:[23,49,50],newer:[13,25,47],newi:13,newz:13,next:[10,20,23,39,40,42,47,48,50,53],nexu:[6,8,14],ngd:[13,30],ngdbuild:[13,30],ngo:30,ni:25,nocas:40,noconfig:41,nodangl:6,node:[8,9,18,20,23],non:[6,20,23,30,38,50],none:[4,10,20,23,55],nor:[20,23],normal:[0,6,12,17,20,22,23,25,41,42,45,47,48,50,53],notabl:41,notat:[8,20],note:[0,3,6,8,9,11,12,13,20,21,23,25,30,34,40,41,42,47,49,50,53,55,56],noth:[20,30],notic:[10,23,49,50,53],notif:23,novemb:41,now:[0,8,10,13,20,26,47,54],nt:13,nul:20,num:[20,48],number:[8,9,10,16,20,21,30,41,48,50],numer:[10,20,22],o2:0,o:[0,6,13,29,30,33,34,35,37,38,39,41,42,43,48,49,50,53],obj:20,object:[0,1,2,4,6,7,8,10,12,14,20,21,22,23,50,51,53,54],oblivion:10,obsolet:[30,41],obtain:47,obuf:30,obviou:[8,10,21,23,44],obvious:[2,10,22,23,53],occur:[8,20,23,48],octob:[40,41],odd:[6,49],off:[20,38,42,44,48,54,55],offer:[0,10,50],offset:20,ofoo:[33,41],often:[1,22,49,50],ohello:53,ok:20,ol:13,old:[13,20],older:[13,30,41,47],omit:[40,44],onc:[0,8,9,10,12,20,21,23,42,43,47,50,53,54],one:[0,6,8,10,13,20,21,22,23,29,30,39,40,41,42,45,48,49,50,54],ones:21,ongo:41,onli:[0,2,4,6,8,10,16,20,21,22,23,26,29,33,37,40,41,42,44,47,48,50,51,52,53,55,56],onto:[20,23,44],op:[20,21],opcod:[3,19,23],open:[48,49],oper:[2,8,9,10,20,22,23,38,40,42,44,47,53],operand:[8,10,20,21,22,23,44],opinion:10,oppos:10,opposit:[20,23],opt:47,optim:[3,6,7,8,20,50],option:[3,16,20,21,22,23,40,41,44,48,50],order:[0,8,9,10,13,17,20,21,23,30,39,40,41,47,48,50,53,55],ordinari:53,organ:[42,53],orient:3,origin:[0,20,21,23,38,44,47,48],osqrt_plusarg:50,osqrt_readmem:50,other:[3,4,6,8,10,14,16,17,20,21,23,29,33,38,40,41,42,43,44,45,47,48,50,51,54],otherwis:[2,3,8,10,20,41,44,47,49,50,53,55],our:[42,49],out:[0,2,4,8,10,12,20,22,23,29,30,33,34,37,38,41,42,43,45,49,50,53],output:[0,3,6,8,10,13,14,18,20,21,23,25,29,30,32,33,34,35,37,41,42,43,47,48,50,53,54,55,56],output_symbol:10,outputsact:13,outsid:[40,47,50,53],over:[0,6,8,23,30,37,38,40,41,47],overal:[20,53],overflow:[10,20],overlap:20,overrid:[3,8,23,33,40,41,48,55],overridden:33,own:[8,50],p10:30,p20:30,p21:30,p22:30,p:[8,13,23,30,41],p_123:23,pack:[0,23],packag:[26,28,29,37,40,47,52,54],pad:[4,20,23],page:[0,27,40,41,49],pai:[13,55],pair:23,pal:[27,28],pallowsign:38,panel:40,par:[13,30],parallel:[13,56],param:23,paramet:[3,8,9,10,20,21,30,35,37,40,41,42,43,48,50,53],parameter:[1,7,10],parch:30,pare:20,parent:[8,20,21,23,50],parentag:23,pars:[3,8,10,17,23,41,47,50,52,55],parser:[3,10,21,23,48],part:[3,10,12,13,17,20,30,37,38,41,42,50,53],parti:[2,50,53],partial:[1,41],particip:3,particular:[3,8,10,13,16,20,21,22,23,29,47],partner:20,partselsynth:38,pass:[0,3,8,9,10,17,20,21,23,25,34,35,40,41,44,47,48,50,53,54],passiv:8,past:37,patch:[0,47,49],path:[9,13,17,18,25,29,33,40,41,45,47,48,50,52,55],pattern:[10,50],paus:20,pc:[13,22],pcb:[27,28],pdebug:37,pdepth:37,peek:20,peopl:[0,42],per:[8,40,41,42,47,50],perfectli:10,perform:[3,6,9,20,23,41,50,53,55],period:0,perl:25,permut:41,person:[10,49],perspect:21,pexpr:3,pfilelin:38,pform:[3,8],pgener:3,phantom:23,phase:[8,30,41],pi:16,pick:[8,44],pid:20,pilotscop:13,pin:[4,8,13],pkg:52,pl:0,place:[6,8,10,13,16,20,21,23,25,37,38,40,41,42,47,48,50,52,53],placement:13,plain:23,plan:[20,53],plate:6,platform:[12,20],pld:6,pleas:[8,49,50],pli1:[3,53],pli:[1,2,3,17,51,55],plu:55,plusarg:[25,40,43,50],pnetlist:33,point:[0,2,6,8,10,12,20,23,40,47,49,53],pointer:[8,9,21,23,53],poke:23,polybu:13,pool:[0,47],poorli:10,pop:[20,54],popul:[45,47],port:[4,6,8,10,13,20,23,29,38,41,44,54],portabl:[10,30,43,45],portbind:41,portion:53,posedg:[10,13,23,34,42,43,50,54],posit:[10,20,23,41],possibl:[3,8,10,17,20,22,23,30,40,50,54,56],post:[13,23],potenti:[3,8,50,53],pow:[16,20],power:[8,16,23,38],ppart:30,pq240:30,pr1723367:38,pr:[0,49],practic:[3,8,10,40,50],pre:[3,47,50],preced:[10,23,41],precis:[8,10,20,21,23,35,39,40],precompil:[0,47],predefin:[48,50],predict:[10,20],prefer:[0,33,53,55],prefix:[4,16,41,47],preliminari:[3,11],prepackag:[43,47],prepar:[49,55],prepend:18,preprocess:[41,48,50],preprocessor:[3,27,40,46],prescrib:41,present:[10,23,25,30,41,45,54,56],preserv:[8,23],presum:13,pretti:[17,25],prevent:[4,42,49],previou:[10,21,23,50],previous:[20,23],prim:40,prime:3,primit:[1,4,10,23,30,44,50,51],principl:[20,53],print:[10,18,20,34,37,41,48,54,55],printer:13,prior:53,privat:[17,22,23],pro:30,probabl:[0,8,40,41,47,51],probe:54,problem:[10,17,49],proce:23,procedur:[1,7,8,10,13,20,23,47],procedural_timing_control_stat:10,process:[3,6,8,9,13,23,25,28,29,37,40,41,42,47,48,50],processor:[1,3,10,20,22,23],prod:23,produc:[8,10,20,23,41,42],product:[2,17,20,49,53],progam:47,program:[0,1,3,8,10,13,16,20,21,22,23,25,26,33,37,38,40,41,42,43,47,48,49,50,52,53,54,55,56],programm:[1,4,6,8,10,23,32,40,41,48,50,53],progress:[37,41,50,55],proj_librari:40,project:[38,40],prompt:[42,54],prop:20,propag:[3,8,10,20,23,50],proper:[12,23,30,48,53],properli:[8,10,25,30,41,50],properti:[7,8,20],propos:44,provid:[0,3,6,12,16,20,21,23,44,47,48,53],provision:12,pscope:3,pseudo:[13,21,23],pspace:38,psymbol:23,pub:13,publish:[16,20,21,22,23],pull:[20,22,26,38,40,47,50],pullnon:13,pullup:13,puls:[10,20,42,43],purpos:[4,16,20,21,22,23,42,50],push:[0,4,20,23,47,54],push_back:20,push_front:20,pushi:20,pushv:20,pushx:20,put:[13,20,23,50,54],putc:20,pv:23,py:25,q:[10,23],qb:20,qf:20,qpop:20,queri:26,question:[10,20,30],queue:[20,23],quickli:50,quirk:[27,46],quit:[10,21,53],quot:[10,48],r0:10,r:[8,16,20,23,41],race:[4,23],rais:[20,37],ram:8,ran:25,random:53,randomli:23,rang:[10,41,50],rare:[41,50],rather:[3,13],rc:26,rdy1:50,rdy2:50,rdy:50,re:[0,25,26,41,47],reach:10,react:8,read:[1,8,10,20,21,22,23,29,37,40,42,45,48,50,53],read_blif:29,readabl:23,readabort:13,readcaptur:13,readclk:13,readi:[0,6,23,50],readili:23,readm:20,readmemb:45,readmemh:[45,50],real:[10,16,20,22,23,37,38,44,50],reala:20,realli:[8,10,20,23,42,50],realtobit:53,reap:23,reappear:49,reason:[8,10,13,49,50,51],receiv:[0,10,16,20,21,22,23,50],recent:16,recip:47,recogn:[3,8],recollect:30,recompil:[50,56],record:[6,23,29,30,40,52],recurs:8,redefin:41,redefinit:41,redistribut:[16,20,21,22,23],reduc:[23,50],reduct:[10,20],refer:[0,1,8,10,16,20,21,23,40,41,47,50],referenc:[8,10,23,50,51],reflect:[6,10,20,48,50,53],reg:[4,10,14,20,21,23,34,42,43,44,45,50,51,54],region:23,regist:[2,8,20,21,22,23,53],regress:[24,26,27,49],regular:[23,25,42,43],rejoin:23,rel:[25,41,48,50],relat:[21,42,49],relationship:8,releas:[20,23,37,40,41,47,49],reliev:6,remain:[9,20,22,23,41,50],rememb:[0,47],remot:[0,13,47],remote_alli:13,remote_dir:13,remov:[20,41,44,48,55],renam:30,repeat:[3,9,10,38],repetit:20,replac:[6,7,20,23,25,41],replic:[20,22,23],report:[4,10,20,25,27,44,46],repositori:[0,3,47],repres:[1,6,7,8,9,14,16,20,21,23,42,50],represent:50,reproduc:49,rept:23,request:[21,53],requir:[0,10,23,41,42,50,53],rerun:[0,50],reschedul:20,reserv:[8,20,22],reset:[23,34,41,42,43,50],resolut:[8,23,50],resolv:[0,4,8,10,14,18,21,30,41,44,50],resort:30,resourc:23,respond:[20,23],respons:20,rest:[6,23,43,49,53],restart:20,restrict:[10,40,44,56],result:[0,10,16,20,23,26,34,35,37,39,41,42,44,48,50],resum:[20,21,54],ret:20,retest:50,retload:20,retriev:[8,9,23],reuqest:0,reus:[0,23],review:0,rh:41,rich:40,right:[0,8,9,10,20,23,41,47,55],rise:[10,23],risk:41,rnan:10,robustli:13,rom:50,root:[0,3,4,8,16,21,23,29,35,40,41,42,47,48,50],round:10,rout:13,routin:[17,21,53],row0:23,row1:23,row:[23,49],rpm:[26,47],rpn:20,rule:[6,10,13,20,21,23,41],rummag:54,rumor:10,run:[0,2,10,12,17,20,21,23,25,39,41,42,43,45,47,48,50,53,55,56],run_defparam:3,runnabl:20,runtim:[1,21,41,42,43,53,55],runtin:41,rv:20,s20221226:39,s:[0,6,10,12,13,20,23,30,34,35,39,41,42,47,49,53,54,55],s_0x563c3c5d1540:39,s_vpi_systf_data:53,safe:[50,53],sai:[0,10,13,23],said:23,sake:23,same:[2,6,8,10,12,16,20,21,23,30,38,40,41,42,44,48,50,52,53,54],sampl:[8,40,49,50,52,53,54],sample1:10,sample2:10,save:[42,49,53],sb:20,scalar:[21,23,41],scale:[10,23],scan:[2,3,8,17,43,53],scanf:10,schedul:[4,10,20,23,54],schedule_simul:23,scheme:[0,3],scope:[3,20,34,35,39,41,43,47,50,54],scp:13,script:[0,13,25,26,47],scroll:3,seamless:[2,53],search:[10,17,27,40,41,42,45,48,50,52,53,55],second:[10,23,42],section:[0,4,9,10,23,24,25,30,46,50],see:[0,1,3,4,7,8,10,12,13,16,17,20,21,22,23,41,47,49,50,54],seem:[10,13],seen:39,sel:20,select:[0,10,20,28,30,38,39,41,42,47,48,49,50],selector:41,self:10,semant:[3,10,20],semicolon:23,send:[20,28,48,55],sens:[6,8,10,23,50],sensit:[20,41],sent:[20,48,50],sentenc:10,separ:[3,4,17,20,23,25,40,41,44,45,48,50],sequ:23,sequenc:[13,40,42,50],sequenti:[23,29],set:[0,3,4,6,8,9,10,12,17,18,20,21,22,23,25,30,33,38,39,40,41,48,49,50,54,55],set_width:8,setenv:17,setup:[12,13,23],sever:[3,23,37,41,50],sft:53,sh:[0,47],shall:10,share:[0,2,6,12,40,41,47,50,53,56],shebang:[39,41],shell:[13,39,40],shift:[20,23,38],shiftl:20,shiftr:20,shorthand:[20,23,40,54],should:[0,8,10,12,16,20,21,22,23,26,30,38,41,44,47,49,50,55,56],show:[10,12,54,55],shown:[42,49],side:41,sig:30,sign:[8,10,20,23,38,53],signal:[3,4,8,14,20,23,30,35,38,41,43,51],signific:[9,10,20,23,40],silent:23,similar:[6,20,21,23,25,30,39,40,41,44,50],similarli:[3,10,23,37],simpl:[0,10,13,25,42,47,48,50,53],simplest:[42,50],simpli:[10,17,20,22,23,42,50],simplif:8,simplifi:25,simul:[0,1,3,4,6,12,19,20,21,27,39,41,42,43,46,47,53,54,55,56],simulatorvers:26,sin:16,sinc:[10,20,21,23,29,30,41,47,53,56],sine:16,singl:[8,14,17,20,21,22,23,30,37,38,41,42,50,53,54,56],singli:[22,23],sinh:16,site:[0,47],situat:[3,10,40,48],size:[8,10,20,23,42],sizer:[27,28],sizetf:53,skip:[20,23,25,41,53],slash:40,sleep:20,slice:34,slightli:50,slow:13,small:[6,23,42,47,49,56],smaller:[20,23,49,50],smartmodel:12,snapshot:[40,41,49,51],so:[0,1,2,3,6,7,8,9,10,12,13,17,18,20,21,23,25,29,30,39,40,41,42,44,45,47,48,49,50,53,54,55,56],soff:23,softwar:[12,13,16,17,20,21,22,23,47,56],sol:12,solari:[12,13],sole:41,solut:53,some:[3,8,10,13,14,18,21,23,30,33,38,39,40,41,42,44,50,51,53,54,55,56],somebodi:10,someth:[23,26,38,39,45,49],sometim:[1,20,23,29,41,50],somewhat:[20,44],somewher:[10,50],soon:[8,10],sort:[10,20,21,23,42],sourc:[0,1,3,4,6,8,10,12,20,21,22,23,26,29,33,37,40,41,42,48,49,50,53],space:[20,22,23,38,40,41,48,50],span:[23,40],spare:20,spartan:13,spawn:20,speak:[10,44],spec:26,special:[3,6,17,20,21,22,23,38,40,41,47,50,53,55,56],specif:[1,4,6,7,8,10,20,21,23,26,30,39,41,42,43,50,51,53],specifi:[2,6,8,9,10,17,18,20,21,23,25,30,39,40,41,43,44,45,47,48,50,53,55],spite:8,split:20,spontan:50,spread:[37,38,42],sqrt32:50,sqrt:[16,50],sqrt_plusarg:50,sqrt_readmem:50,squar:[16,50],sr:20,src1:41,src2:41,src:[20,23,41],sroot:42,ssh:[0,13],ssymbol:23,stabl:47,stack:[20,23,54],stai:23,stamp:26,stand:10,standard:[0,1,3,6,7,13,17,21,23,41,44,45,47,48],start:[3,4,12,20,22,23,24,27,40,46,47,48,49,50,51,53,54,55],starther:49,startup:[17,23,53],startupclk:13,state:[8,10,20,23,38,54],statement:[3,4,8,10,12,20,21,22,37,40,41,50,51,52,54],statement_or_nul:10,statist:34,statu:10,std:41,std_logic_1164:37,stderr:[20,25,52,55],stdlog:55,stdout:[25,52,55],step:[0,3,6,8,13,20,22,23,41,42,47,50,53,54],stephen:[12,16,20,21,22,23,49],steve:[13,20,21,22,23],steveicaru:[0,16,47],still:[20,23,25,38,41,50],stop:[20,41,42,54,55],storag:[20,23],store:[8,20,21,23,47,50,52],str:[20,23],stra:20,straight:53,straightforward:56,stream:[3,50,54],street:[16,20,21,22,23],strength:[23,44],stretch:51,strict:[0,41],strictli:[10,44],string:[4,9,16,20,21,23,25,26,30,33,35,40,42,50,55],strip:[23,40],strobe:23,structur:[3,6,21,29,49,50],stuart:53,stub:[6,27,28,47,55,56],stuck:54,stuff:10,style:[20,22,30,38,40],su:47,sub:[8,20,21,23,29],subcircuit:29,subcommand:3,subdirectori:3,subi:20,submiss:49,submit:[0,47,49],subsequ:[8,10],subset:[21,29],substitut:[48,50],substr:20,subsum:20,subtract:20,subvector:20,succe:25,succumb:8,sudo:0,suf:41,suffici:[23,41],suffix:[0,23,40,42,47,55],suggest:[10,16,40,47],suit:[0,24,27,49],suitabl:30,sum:23,summar:41,summari:[4,23],summarili:49,supoprt:41,support:[1,3,4,6,7,8,9,10,11,17,20,21,23,27,29,30,38,40,41,42,43,44,46,48,53],suppos:[10,12,30],suppress:20,sure:[0,25,47],surround:[23,40],suspect:[41,54],suspend:[20,23],sutherland:53,sv:41,swapnajit:53,swid:23,swift:[3,11],swift_boot:12,swiftpli:12,symbol:[3,8,10,17,21,40,41,48,53],symbol_list:23,symbols_list:23,syn:6,sync:[0,47],synchron:[0,23],synctodon:13,synonym:[54,55],synopsi:12,syntact:40,syntax:[1,6,10,21,30,33,40,41,44,50,51],synth2:[6,41],synth:[6,7],synthes:[4,7,13,34,41,50,51],synthesi:[1,3,6,7,8,10,23,29,41,53],synthesiz:[4,50],synthet:23,system:[0,2,3,6,10,12,16,17,20,23,29,38,39,40,41,42,43,47,50,54,55],systemverilog:[20,29,41,44],t:[1,6,10,13,17,20,23,25,26,28,29,30,37,41,42,43,45,47,49,53,55],t_0:39,t_label:20,tabl:[1,2,3,10,17,20,39,53,54],tag:[0,7,23,26,47],tail:20,take:[0,3,6,8,10,20,21,22,23,30,40,41,42,43,44,47,50,53,55],taken:[3,6,20,23,40,44,53,54],tan:16,tangent:16,tanh:16,tar:13,target:[1,3,4,5,7,8,13,20,23,25,26,27,29,31,32,33,34,39,50,51],target_design:6,task:[2,3,10,12,17,20,38,43,44,48,50,53,54,55],tbase:23,tblif:[27,28],tdll:9,tdopin:13,technic:10,techniqu:[42,50],technolog:[1,7,50,51],tediou:50,tell:[4,6,8,10,12,20,30,39,40,41,42,47,50,51,52,53,54],temp:13,temporari:8,term:[1,16,20,21,22,23,49],termim:54,termin:[20,23,39,40,47,53,54],ternari:20,test1:52,test2:52,test3:52,test:[4,10,13,20,24,26,27,37,40,42,43,49,50,51],test_nul:20,testbench:50,text:[10,17,20,23,30,33,35,40,41,42,45,50,56],textual:[10,50],tf_data:53,tfname:53,tfpga:[27,28],tgt:[3,6],th:26,than:[10,13,20,21,23,38,42,47,48,50],thei:[1,4,6,7,8,10,12,13,16,20,21,22,23,25,40,41,42,44,47,49,50,51,53,55],them:[0,1,20,23,26,41,42,48,50,53,55],themselv:[21,23],therefor:[4,8,10,21,25,30,50],therein:52,thi:[0,1,2,3,4,6,8,9,10,12,13,14,16,17,18,20,21,22,23,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56],thing:[10,23,25,38,42],think:[10,20,49],third:[2,23,50,53],those:[0,3,8,10,13,20,23,25,45,47,50,53],though:[10,21,23,49],thr:20,thread:[3,4,10,19,20,21,39],three:[8,10,20,23,41],through:[0,2,6,8,13,20,21,22,23,40,44,47,49,50,53],throughout:[1,23,54],thu:[10,21,23,53],tick:[20,23,54],tickl:23,time:[0,4,6,10,13,17,20,21,23,25,35,39,41,42,43,47,48,50,53,54,55],time_precis:8,time_unit:8,timescal:[10,21,39,40,41],tini:42,tip:53,titl:49,tmax:41,tmin:41,tmp:[10,17],tnull:[27,28],todo:37,togeth:[8,17,20,23,40,42,50,53],token:[3,4,21,23,40,50,52],told:50,tolow:40,too:[10,41],tool:[0,3,4,10,18,23,29,30,41,44,47,51,53],top:[20,23,34,35,37,39,40,41,43,49],topic:53,topmodul:41,total:[0,23,34],toupper:40,toward:[10,20],tpal:[27,28],tpcb:[27,28],trace:[20,54,55],track:[0,23,47,48,49,50,53],tracker:49,trail:[40,41,48],tran:38,transfer:23,transform:[3,8,50],transit:[8,23],translat:[1,3,7,8,37,38,40],transpar:13,trap:23,treat:[10,20,23,41],tree:[0,3,8,14,21,47],tri0:23,tri1:23,tri:[4,13,18,23,44],trick:10,tricki:21,trigger:[8,20,23,41],tring:33,trivial:42,troubl:[42,49],truncat:[10,20,41],truth:[1,20],tsizer:34,tstub:[27,28],ttyp:41,turn:[2,3,9,10,12,13,21,23,41,42,44,49,50,53,55],tverilog:[27,28],tvhdl:[27,28],tvlog95:[25,27,28],tvvp:[25,27,28,49],twice:10,twid:23,two:[1,6,8,10,17,20,23,37,39,42,47,50],txt:[12,13,17,20,23,34,35,42,45],type:[0,6,8,10,20,21,23,30,33,35,41,50,55],typic:[8,23,39,41,42,47,55,56],u1:10,u2:10,u3:10,u4:10,u5:10,u6:10,u:[0,20,23,37,41],udp:1,ufunc:[6,23],uint64_t:23,ultim:[10,21],unaccount:34,unclear:10,uncondit:20,uncondition:20,unconnect:[8,10,23],undeclar:10,undecor:41,undefin:[20,23,38,41],under:[2,16,17,20,21,22,23,40,42,47,49,50,53],underflow:50,underli:[16,50],underneath:20,understand:[4,7,10,30,48,49,50,51],unforc:20,unfortun:10,unifi:30,uniqu:50,unit:[8,21,23,35,40,41,54],unix:[40,42,53],unknown:[0,10,20],unless:[20,23,30,50],unlik:[21,23],unload:56,unread:8,unresolv:23,unrol:38,unsign:[8,10,20,23,38,53],unsiz:[8,10,41],unspecifi:[10,55],unsplit:20,until:[8,10,17,20,23,50],unusu:40,unwant:42,up:[0,8,10,20,22,23,47,50,53,54,55],updat:[13,44,47],upper:0,uppercas:40,upstream:0,ur:20,us:[0,1,2,3,4,6,8,9,10,12,13,14,20,21,22,23,25,26,27,29,30,33,37,39,40,41,42,43,44,45,46,47,48,49,51,52,54,55,56],usa:[16,20,21,22,23],usag:[27,41,48,54,55],useless:50,user:[0,1,2,3,4,6,7,9,10,20,21,23,30,33,40,41,42,43,46,47,50,53,55],user_data:53,usr:[0,6,39,47],usual:[2,8,20,22,23,30,33,44,50,53],v0:[0,20,41,47],v11:[0,41,47,53,55],v12:26,v2005_math:[17,39],v2009:17,v50:30,v:[20,23,25,33,34,35,37,38,39,40,41,42,43,48,49,50,52,53,55],v_:14,va_math:[16,17,39],val:[10,20],vala:20,valb:20,valgrind:[0,47],valid:[0,10,13,20,23,25,44,48,50],valu:[3,4,8,9,10,14,16,20,21,22,23,25,30,33,38,39,40,41,42,43,44,45,48,50,55],vam:16,vams_simparam:26,vari:[6,10,13],variabl:[10,12,14,17,18,20,37,38,41,44,50,53,54,56],variant:[20,23,41,44],variat:[20,23,50],varieti:[1,7,10,23,30,40,47,50],variou:[9,18,23,33,38,39,40,41,42,50,51,54],vcd:[10,43],ve:[0,10,47],vec2:20,vec4:[20,23],vec4a:20,vec:10,vector2:20,vector4:20,vector:[6,8,10,20,21,22,29,30,38,41,44],vector_wid:23,vendor:[40,50],ver:[40,42],verbos:[17,41,52,55],veri:[0,10,20,23,30,40,47,49],verif:29,verifi:41,verilog:[1,2,3,5,6,7,8,9,10,12,20,21,22,23,25,26,29,30,32,33,34,35,37,39,40,41,43,47,48,49,52,53,55],verilogxl:12,verion:26,veriusertf:[2,53],version:[0,6,10,13,16,20,21,22,23,24,27,39,40,41,47,48,49,52,53],version_bas:26,version_tag:[0,26],vhd:37,vhdl:[17,27,28,29,40,48,52],vhdl_sy:[17,39],vhdl_textio:[17,39],vhdlpp:[0,27,46,48],via:[0,3,6,8,12,13,23,29,53,55],view:[10,43,55],viewer:[10,43,50],violat:10,virtex2:30,virtex:30,virtual:[1,3,8,23],visit:37,vl:[30,40,42,48,49,50,54],vlg:42,vlh:48,vlog95:25,vlog_startup_routin:[17,53],vp:38,vpi:[1,3,6,16,19,20,26,27,39,41,46,50,51,54,55,56],vpi_cal:[20,21,23,39],vpi_func:[20,23],vpi_ipoint_t:21,vpi_modul:39,vpi_module_path:[17,23],vpi_printf:53,vpi_register_systf:[21,53],vpi_time_precis:[23,39],vpi_trac:17,vpi_us:[41,53],vpifullnam:21,vpihandl:[20,21,23],vpiintegervar:23,vpiinternalscop:21,vpip_set_callback:17,vpiparamet:23,vpireg:21,vpiscop:21,vpistringvar:23,vpisysfuncint:53,vpisysfuncr:53,vpisysfuncs:53,vpisystask:53,vpisystaskcal:21,vpisystfcal:21,vpl:[2,53],vr:20,vs:10,vvm:1,vvp:[0,1,2,3,4,6,12,17,20,22,26,27,28,40,41,42,43,45,46,47,50,53],vvp_debug:18,vvp_ipoint_t:23,vvp_reg:[0,25],vvp_test:25,vvp_vector8_t:23,w64:47,w:[13,23,30,41,52],wa:[2,10,20,21,38,39,41,47,53,56],wade:49,wai:[0,4,6,8,10,23,25,40,41,44,45,47,48,50,54,56],wait:[20,23,50],waitfor:23,wake:23,walk:8,wall:[0,41],wanachron:41,want:[0,8,10,17,20,23,45,47,49,54],warn:[4,23,34,38,41,55],warrant:[20,23],warranti:[16,20,21,22,23],watch:23,waveform:[23,27,46,50,55],we:[0,1,6,8,10,20,23,39,41,42,45,47,49,50,53,54],weak:10,web:[3,21,23],welcom:[27,49],well:[10,20,23,41,49,53,54],weq:23,were:[2,10,20,50,53],wextra:0,what:[0,3,5,6,8,10,12,20,22,23,30,39,41,42,47,49,50,54],whatev:[10,17,21,29,42,49],when:[0,1,6,7,8,10,12,17,20,21,23,26,30,34,40,41,42,43,47,50,52,53,54,55],whenev:[8,20,23,50],where:[3,4,6,8,10,14,17,20,22,23,25,30,37,38,40,41,42,45,47,48,49,50,52,53,54,55],wherea:[6,8,10,20,23,37,50],whether:[0,6,10,23,41],which:[3,6,8,10,13,14,20,21,22,23,25,30,39,40,41,42,43,44,47,50,51,55],whim:17,white:[40,48],who:[13,24,47,49,53],whole:40,why:[10,49],wid:[20,23,53],wide:[1,10,20,23,30,50],wider:23,width:[6,9,10,20,22,23,35,40,41,42,43],wild:[10,20],william:[12,16,20,21,22,23,49],wimplicit:41,win:49,window:[26,40,42],wire:[4,8,10,14,23,41,42,43,44,50,51,54],wish:[13,17,50,53],within:[3,4,8,9,10,13,19,20,23,33,40,41,42,50,52,54],without:[1,7,10,16,20,21,22,23,25,40,41,48,50,56],wmacro:41,wne:[20,23],word:[3,10,20,23,29,41],work:[0,1,2,3,8,10,12,17,20,21,22,23,25,30,40,42,45,47,48,49,50,52,56],workdir:40,world:[1,2,23,35,39,42,50,53,54],worth:26,would:[2,10,16,23,30,47,49,50,53],wportbind:41,wr:20,wrap:[12,14],wrapper:[12,21],write:[0,6,8,9,10,16,20,21,22,23,30,33,41,42,49,50,53],writer:[3,6],writeup:47,written:[3,10,12,17,20,21,23,25,30,33,41,42,43,50],wrong:[10,21,49],wselect:41,wsensit:41,wshadow:0,wtimescal:41,www:[13,29],x0:23,x1:23,x86_64:[0,47],x86_linux:12,x:[9,10,13,16,20,22,23,26,37,41,44,50,53],xcode:47,xcs10:13,xess:13,xilinx:[3,11],xilinx_on_linux:13,xilix:41,xl:[2,3,10,53],xnf2pcf:13,xnf:13,xnfsyn:13,xnor:[20,23],xor:[20,23],xsp:13,xstool:13,xtype:[41,44],xxx:26,xxxx:20,xz:20,y1:50,y2:50,y:[3,10,13,16,23,40,41,50],yahoo:16,ye:[0,13],yet:[1,4,7,8,10,12,13,50],yield:[10,20],you:[0,3,6,12,13,16,17,20,21,22,23,25,26,30,39,41,42,43,45,47,49,50,53,54,55],your:[0,6,12,13,16,17,20,21,22,23,30,40,42,43,45,47,49,50,52,53,54,55],your_input_her:13,your_output_her:13,yourpublicemail:47,yydebug:52,z:[9,10,13,20,22,23,44,50],zero:[10,20,23,37,38,41],zip:13,zone:10,zzxx1100:23},titles:["Getting Started as a Contributer","Glossary","Cadence PLI1 Modules","Developer Guide","Icarus Verilog Attributes","IVL - The Core Compiler","Loadable Target API (ivl_target)","What Is LPM","Netlist Format","Loadable Targets","IEEE1364 Notes","Miscellaneous","Swift Model Support (Preliminary)","Xilinx Hint","The VVP Target","VPI in Icarus Verilog","Verilog-A math library","VPI Modules in Icarus Verilog","Debug Aids For VVP","VVP - Verilog Virtual Processor","Executable Instruction Opcodes","VPI Within VVP","Thread Details","VVP Simulation Engine","Icarus Verilog Developer Support","The Regression Test Suite","Files With Version Information","Icarus Verilog","The Icarus Verilog Targets","The BLIF Code Generator (-tblif)","The FPGA Code Generator (-tfpga)","The null Code Generator (-tnull)","The PAL Code Generator (-tpal)","The PCB Code Generator (-tpcb)","The sizer Code Analyzer (-tvvp)","The stub Code Generator (-tstub)","The Verilog Code Generator (-tverilog)","The VHDL Code Generator (-tvhdl)","The Verilog \u201895 Code Generator (-tvlog95)","The vvp Code Generator (-tvvp)","Command File Format","iverilog Command Line Flags","Getting Started With Icarus Verilog","Waveforms With GTKWave","Icarus Verilog Extensions","Icarus Verilog Quirks","Icarus Verilog Usage","Installation Guide","IVLPP - IVL Preprocessor","Reporting Issues","Simulation Using Icarus Verilog","Verilog Attributes","vhdlpp Command Line Flags","Using VPI","VVP Interactive Mode","VVP Command Line Flags","VVP as a library"],titleterms:{"1995":38,"95":38,"class":8,"function":[16,21,23,44,53],"new":23,"null":31,"return":53,A:[16,17,43,49,53],AND:30,And:[8,23],For:18,In:8,Is:7,It:53,Not:37,Of:[7,8],THE:30,The:[3,5,6,14,23,25,28,29,30,31,32,33,34,35,36,37,38,39,50],There:23,To:[4,23,49],WITH:30,With:[26,42,43],about:9,advanc:50,aid:18,alloc:23,an:40,analyz:34,api:[6,9],arg:[25,40],argument:[21,55],arithmet:23,arrai:23,assign:30,attribut:[4,33,51],automat:[23,50],behavior:8,between:23,bit:8,blif:29,branch:0,brows:54,built:44,cadenc:[2,53],call:[21,23],cannot:38,cast:23,code:[29,30,31,32,33,34,35,36,37,38,39],command:[40,41,50,52,55],comment:40,compar:23,compat:38,compil:[0,3,5,6,9,17,23,30,47,50,53],compon:3,concaten:23,config:6,configur:[0,47],constant:16,construct:37,content:27,contribut:0,control:4,convent:[4,14],convert:38,core:[3,5],creat:[6,49],data:[44,50],debug:18,delai:23,deriv:8,descript:25,design:54,detail:22,develop:[3,24],devic:[6,30],dff:23,direct:48,download:13,edif:30,elabor:[41,50],engin:23,enter:54,environ:55,event:23,exampl:[40,43,53],execut:[20,23],expans:23,express:[8,9],extend:[25,44,55],extens:44,file:[6,13,26,40,48,50],flag:[20,33,37,38,41,48,52,55],forc:23,fork:0,format:[8,23,40,52],foundat:30,fpga:30,from:[23,47],fst:55,functor:[14,23],further:3,gener:[13,14,23,29,30,31,32,33,35,36,37,38,39,41,48],get:[0,23,42],glossari:1,gold:25,good:49,gtkwave:43,guid:[3,47],header:23,here:23,hierarchi:8,hint:13,how:[23,49,53],icaru:[0,4,15,17,24,27,28,42,44,45,46,47,50],ieee1364:10,implement:23,includ:48,index:23,indic:27,inform:26,input:50,instal:[6,47],instruct:[20,23],interact:[8,54],intern:7,invoc:[33,37,38],invok:30,issu:[10,38,49],item:8,iverilog:[25,41],ivl:[5,13,48],ivl_target:6,ivlpp:48,known:38,label:23,latch:23,leav:54,librari:[16,50,52,56],licens:16,limit:[29,37,38],line:[41,48,52,55],link:8,linux:[0,47],load:[9,21],loadabl:[6,9],locat:48,logic:23,lpm:[6,7],lxt:55,macintosh:47,macro:50,make:50,math:16,mathemat:16,me:23,memori:8,method:23,misc:4,miscellan:11,mode:54,model:12,modul:[2,6,9,17,21,23,50,53],name:[4,14,40],net:23,netassign_:8,netesign:8,netlist:8,netnet:8,netnod:8,netproc:8,netproctop:8,note:10,number:23,old:23,opcod:[20,39],optim:51,option:[0,25,47,55],os:47,other:[37,53],pad:30,pal:32,paramet:[23,33],part:23,path:23,pcb:33,pcf:13,pin:30,pli1:2,pli:53,plu:40,port:30,preliminari:12,preprocessor:[41,48,50],processor:19,pull:[0,49],quirk:45,read:3,readmempath:45,reduct:23,refer:53,regress:[0,25],relationship:23,remov:23,repeat:23,report:49,represent:8,request:[0,49],requir:25,resolut:37,resolv:23,root:30,run:13,runtim:[3,50],scale:8,scope:[8,21,23],sdf:55,select:23,shifter:23,signal:37,simul:[23,50],sizer:34,sourc:[25,47],special:30,specif:[0,9,47],standard:[10,16],start:[0,42],statement:23,structur:[8,14,23,38],stub:35,substitut:[23,40],suit:25,summari:[33,40],support:[12,24,37,55],swift:12,symbol:[14,23],syntax:23,synthesi:[4,51],system:[21,44,45,53],tabl:[23,27],target:[6,9,14,28,30,41],task:[8,21,23,45],tblif:29,test:[0,25],tfpga:30,thank:16,thread:[22,23],time:8,tnull:31,tpal:32,tpcb:33,trace:17,truth:23,tstub:35,tverilog:36,tvhdl:37,tvlog95:38,tvvp:[34,39],type:[9,25,44,53],udp:23,uniqu:45,unix:47,us:[7,16,17,50,53],usag:[29,46],valu:37,variabl:[21,23,40,55],vcd:55,vector:23,verilog:[0,4,13,15,16,17,19,24,27,28,36,38,42,44,45,46,50,51],version:26,vhdl:37,vhdlpp:52,virtual:19,vpi:[15,17,21,23,53],vvp:[14,18,19,21,23,25,39,54,55,56],waveform:43,web:14,what:7,width:8,window:47,within:21,work:[43,53],x:47,xilinx:[13,30],xnf:30}}) \ No newline at end of file diff --git a/targets/index.html b/targets/index.html new file mode 100644 index 0000000000..912f0417b6 --- /dev/null +++ b/targets/index.html @@ -0,0 +1,144 @@ + + + + + + + + + The Icarus Verilog Targets — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

The Icarus Verilog Targets

+

Icarus Verilog elaborates the design, then sends to the design to code +generates (targets) for processing. New code generators can be added by +external packages, but these are the code generators that are bundled with +Icarus Verilog. The code generator is selected by the “-t” command line flag.

+ +
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/targets/tgt-blif.html b/targets/tgt-blif.html new file mode 100644 index 0000000000..eac9fab795 --- /dev/null +++ b/targets/tgt-blif.html @@ -0,0 +1,161 @@ + + + + + + + + + The BLIF Code Generator (-tblif) — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

The BLIF Code Generator (-tblif)

+

The BLIF code generator supports emitting the design to a blif format +file as accepted by:

+
+

ABC: A System for Sequential Synthesis and Verification +<http://www.eecs.berkeley.edu/~alanmi/abc/>

+
+

This package contains tools sometimes used by ASIC designers. This +blif target emits .blif file that the ABC system can read int via +the “read_blif” command.

+
+

USAGE

+

This code generator is intended to process structural Verilog source +code. To convert a design to blif, use this command:

+
% iverilog -tblif -o<path>.blif  <source files>...
+
+
+

The source files can be Verilog, SystemVerilog, VHDL, whatever Icarus +Verilog supports, so long as it elaborates down to the limited subset +that the code generator supports. In other words, the files must be +structural.

+

The root module of the elaborated design becomes the model is +generated. That module may instantiate sub-modules and so on down the +design, completing the design. The output model is flattened, so it +doesn’t invoke any subcircuits. Bit vectors are exploded out at the +model ports and internally. This is necessary since blif in particular +and ABC in general processes bits, not vectors.

+
+
+

LIMITATIONS

+

Currently, only explicit logic gates and continuous assignments are +supported.

+

The design must contain only one root module. The name of that root +module becomes the name of the blif model in the “.model” record.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/targets/tgt-fpga.html b/targets/tgt-fpga.html new file mode 100644 index 0000000000..db94f458f9 --- /dev/null +++ b/targets/tgt-fpga.html @@ -0,0 +1,303 @@ + + + + + + + + + The FPGA Code Generator (-tfpga) — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

The FPGA Code Generator (-tfpga)

+
+

Warning

+

This code generator is currently not included in Icarus Verilog.

+
+

The FPGA code generator supports a variety of FPGA devices, writing +XNF or EDIF depending on the target. You can select the architecture +of the device, and the detailed part name. The architecture is used to +select library primitives, and the detailed part name is written into +the generated file for the use of downstream tools.

+
+

INVOKING THE FPGA TARGET

+

The code generator is invoked with the -tfpga flag to iverilog. It +understands the part= and the arch= parameters, which can be set with +the -p flag of iverilog:

+
+

iverilog -parch=virtex -ppart=v50-pq240-6 -tfpga foo.vl

+
+

This example selects the Virtex architecture, and give the detailed +part number as v50-pq240-6. The output is written into a.out unless a +different output file is specified with the -o flag.

+

The following is a list of architecture types that this code generator +supports.

+
    +
  • arch=lpm

  • +
+

This is a device independent format, where the gates are device types +as defined by the LPM 2 1 0 specification. Some backend tools may take +this format, or users may write interface libraries to connect these +netlists to the device in question.

+
    +
  • arch=generic-edif (obsolete)

  • +
+

This is generic EDIF code. It doesn’t necessarily work because the +external library is not available to the code generator. But, what it +does is generate generic style gates that a portability library can +map to target gates if desired.

+
    +
  • arch=generic-xnf (obsolete)

  • +
+

If this is selected, then the output is formatted as an XNF file, +suitable for most any type of device. The devices that it emits +are generic devices from the unified library. Some devices are macros, +you may need to further resolve the generated XNF to get working +code for your part.

+
    +
  • arch=virtex

  • +
+

If this is selected, then the output is formatted as an EDIF 200 file, +suitable for Virtex class devices. This is supposed to know that you +are targeting a Virtex part, so can generate primitives instead of +using external macros. It includes the VIRTEX internal library, and +should work properly for any Virtex part.

+
    +
  • arch=virtex2

  • +
+

If this is selected, then the output is EDIF 2 0 0 suitable for +Virtex-II and Virtex-II Pro devices. It uses the VIRTEX2 library, but +is very similar to the Virtex target.

+
+
+

XNF ROOT PORTS

+
+

NOTE: As parts are moved over to EDIF format, XNF support will be +phased out. Current Xilinx implementation tools will accept EDIF +format files even for the older parts, and non-Xilinx implementation +tools accept nothing else.

+
+

When the output format is XNF, the code generator will generate “SIG” +records for the signals that are ports of the root module. The name is +declared as an external pin that this macro makes available.

+

The name given to the macro pin is generated from the base name of the +signal. If the signal is one bit wide, then the pin name is exactly +the module port name. If the port is a vector, then the pin number is +given as a vector. For example, the module:

+
module main(out, in);
+    output out;
+    input [2:0] in;
+    [...]
+endmodule
+
+
+

leads to these SIG, records:

+
SIG, main/out, PIN=out
+SIG, main/in<2>, PIN=in2
+SIG, main/in<1>, PIN=in1
+SIG, main/in<0>, PIN=in0
+
+
+
+
+

EDIF ROOT PORTS

+

The EDIF format is more explicit about the interface into an EDIF +file. The code generator uses that control to generate an explicit +interface definition into the design. (This is not the same as the +PADS of a part.) The generated EDIF interface section contains port +definitions, including the proper direction marks.

+

With the (rename …) s-exp in EDIF, it is possible to assign +arbitrary text to port names. The EDIF code generator therefore does +not resort to the mangling that is needed for the XNF target. The base +name of the signal that is an input or output is used as the name of +the port, complete with the proper case.

+

However, since the ports are single bit ports, the name of vectors +includes the string “[0]” where the number is the bit number. For +example, the module:

+
module main(out, in);
+    output out;
+    input [2:0] in;
+    [...]
+endmodule
+
+
+

creates these ports:

+
out   OUTPUT
+in[0] INPUT
+in[1] INPUT
+in[2] INPUT
+
+
+

Target tools, including Xilinx Foundation tools, understand the [] +characters in the name and recollect the signals into a proper bus +when presenting the vector to the user.

+
+
+

PADS AND PIN ASSIGNMENT

+

The ports of a root module may be assigned to specific pins, or to a +generic pad. If a signal (that is a port) has a PAD attribute, then +the value of that attribute is a list of locations, one for each bit +of the signal, that specifies the pin for each bit of the signal. For +example:

+
module main( (* PAD = "P10" *)         output out,
+             (* PAD = "P20,P21,P22" *) input [2:0] in);
+    [...]
+endmodule
+
+
+

In this example, port out is assigned to pin 10, and port in +is assigned to pins 20-22. If the architecture supports it, a pin +number of 0 means let the back end tools choose a pin. The format of +the pin number depends on the architecture family being targeted, so +for example Xilinx family devices take the name that is associated +with the “LOC” attribute.

+

NOTE: If a module port is assigned to a pin (and therefore attached to +a PAD) then it is not connected to a port of the EDIF file. This is +because the PAD (and possibly IBUF or OBUF) would become an extra +driver to the port. An error.

+
+
+

SPECIAL DEVICES

+

The code generator supports the “cellref” attribute attached to logic +devices to cause specific device types be generated, instead of the +usual device that the code generator might generate. For example, to +get a clock buffer out of a Verilog buf:

+
+

buf my_gbuf(out, in); +$attribute(my_buf, “cellref”, “GBUF:O,I”);

+
+

The “cellref” attribute tells the code generator to use the given +cell. The syntax of the value is:

+
+

<cell type>:<pin name>,…

+
+

The cell type is the name of the library part to use. The pin names +are the names of the type in the library, in the order that the logic +device pins are connected.

+
+
+

COMPILING WITH XILINX FOUNDATION

+

Compile a single-file design with command line tools like so:

+
% iverilog -parch=virtex -o foo.edf foo.vl
+% edif2ngd foo.edf foo.ngo
+% ngdbuild -p v50-pq240 foo.ngo foo.ngd
+% map -o map.ncd foo.ngd
+% par -w map.ncd foo.ncd
+
+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/targets/tgt-null.html b/targets/tgt-null.html new file mode 100644 index 0000000000..f5d435e353 --- /dev/null +++ b/targets/tgt-null.html @@ -0,0 +1,129 @@ + + + + + + + + + The null Code Generator (-tnull) — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

The null Code Generator (-tnull)

+

The null target generates no code. Invoking this code generator causes no code +generation to happen.

+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/targets/tgt-pal.html b/targets/tgt-pal.html new file mode 100644 index 0000000000..25e1e66314 --- /dev/null +++ b/targets/tgt-pal.html @@ -0,0 +1,132 @@ + + + + + + + + + The PAL Code Generator (-tpal) — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

The PAL Code Generator (-tpal)

+
+

Warning

+

This code generator is currently not included in Icarus Verilog.

+
+

The PAL target generates JEDEC output for a Programmable Array Logic.

+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/targets/tgt-pcb.html b/targets/tgt-pcb.html new file mode 100644 index 0000000000..4e80ceeb77 --- /dev/null +++ b/targets/tgt-pcb.html @@ -0,0 +1,182 @@ + + + + + + + + + The PCB Code Generator (-tpcb) — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

The PCB Code Generator (-tpcb)

+

The PCB target code generator is designed to allow a user to enter a netlist +in Verilog format, then generate input files for the GNU PCB layout program.

+
+

Invocation

+

The PCB target code generation is invoked with the -tpcb flag to the iverilog +command. The default output file, “a.out”, contains the generated .PCB +file. Use the “-o” flag to set the output file name explicitly. The default +output file contains only the elements. To generate a “netlist” file, add the +flag “-pnetlist=<path>” command line flag.

+

Altogether, this example generates the foo.net and foo.pcb files from the +foo.v source file:

+
% iverilog -tpcb -ofoo.pcb -pnetlist=foo.net foo.v
+
+
+
+
+

Flags

+
    +
  • -o <path>

    +

    Set the output (pcb) file path

    +
  • +
  • -pnetlist=path

    +

    Write a netlist file to the given path.

    +
  • +
+
+
+

Attributes Summary

+

Attributes are attached to various constructs using the Verilog “(* *)” +attribute syntax.

+
    +
  • ivl_black_box

    +

    Attached to a module declaration or module instantiation, this indicates +that the module is a black box. The code generator will create an element +for black box instances.

    +
  • +
+
+
+

Parameters Summary

+

Within modules, The PCB code generator uses certain parameters to control +details. Parameters may have defaults, and can be overridden using the usual +Verilog parameter override syntax. Parameters have preferred types.

+
    +
  • description (string, default=””)

    +

    The “description” is a text string that describes the black box. This string +is written into the description field of the PCB Element.

    +
  • +
  • value (string, default=””)

    +

    The “value” is a text tring that describes some value for the black +box. Like the description, the code generator does not interpret this value, +other then to write it to the appropriate field in the PCB Element.”

    +
  • +
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/targets/tgt-sizer.html b/targets/tgt-sizer.html new file mode 100644 index 0000000000..5945771f8f --- /dev/null +++ b/targets/tgt-sizer.html @@ -0,0 +1,169 @@ + + + + + + + + + The sizer Code Analyzer (-tvvp) — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

The sizer Code Analyzer (-tvvp)

+

The sizer target does not generate any code. Instead it will print statistics about the Verilog code.

+

It is important to synthesize the Verilog code before invoking the sizer. This can be done with the -S flag passed to iverilog. Note, that behavioral code can not be synthesized and will generate a warning when passed to the sizer.

+

Example command:

+
% iverilog -o sizer.txt -tsizer -S -s top input.v
+
+
+

With this example code:

+
module top (
+    input clock,
+    input reset,
+    output blink
+);
+    reg out;
+
+    always @(posedge clock) begin
+        if (reset) begin
+            out = 1'b0;
+        end else begin
+            out <= !out;
+        end
+    end
+
+    assign blink = out;
+
+endmodule
+
+
+

The resulting sizer.txt will contain:

+
**** module/scope: top
+     Flip-Flops   : 1
+     Logic Gates  : 3
+     MUX[2]: 1 slices
+     LOG[13]: 1 unaccounted
+     LOG[14]: 1 unaccounted
+**** TOTALS
+     Flip-Flops   : 1
+     Logic Gates  : 3
+     MUX[2]: 1 slices
+     LOG[13]: 1 unaccounted
+     LOG[14]: 1 unaccounted
+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/targets/tgt-stub.html b/targets/tgt-stub.html new file mode 100644 index 0000000000..208e8f39ae --- /dev/null +++ b/targets/tgt-stub.html @@ -0,0 +1,151 @@ + + + + + + + + + The stub Code Generator (-tstub) — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

The stub Code Generator (-tstub)

+

The stub code generator is a debugging aid for the Icarus Verilog compiler +itself. It outputs a text dump of the elaborated design as it is passed to +code generators.

+

Example command:

+
% iverilog -o stub.txt -tstub -s top input.v
+
+
+

With this example code:

+
module top;
+    initial $display("Hello World!");
+endmodule
+
+
+

The resulting stub.txt will contain:

+
root module = top
+scope: top (0 parameters, 0 signals, 0 logic) module top time units = 1e0
+ time precision = 1e0
+end scope top
+# There are 0 constants detected
+initial
+    Call $display(1 parameters); /* hello_world.v:2 */
+        <string="Hello World!", width=96, type=bool>
+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/targets/tgt-verilog.html b/targets/tgt-verilog.html new file mode 100644 index 0000000000..7e3c004a0a --- /dev/null +++ b/targets/tgt-verilog.html @@ -0,0 +1,131 @@ + + + + + + + + + The Verilog Code Generator (-tverilog) — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/targets/tgt-vhdl.html b/targets/tgt-vhdl.html new file mode 100644 index 0000000000..0a8e212726 --- /dev/null +++ b/targets/tgt-vhdl.html @@ -0,0 +1,195 @@ + + + + + + + + + The VHDL Code Generator (-tvhdl) — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

The VHDL Code Generator (-tvhdl)

+

Icarus Verilog contains a code generator to emit VHDL from the Verilog +netlist. This allows Icarus Verilog to function as a Verilog to VHDL +translator.

+
+

Invocation

+

To translate a Verilog program to VHDL, invoke “iverilog” with the -tvhdl +flag:

+
% iverilog -t vhdl -o my_design.vhd my_design.v
+
+
+

The generated VHDL will be placed in a single file (a.out by default), even if +the Verilog is spread over multiple files.

+
+
+

Flags

+
    +
  • -pdebug=1

    +

    Print progress messages as the code generator visits each part of the +design.

    +
  • +
  • -pdepth=N

    +

    Only output VHDL entities for modules found at depth < N in the +hierarchy. N=0, the default, outputs all entities. For example, -pdepth=1 +outputs only the top-level entity.

    +
  • +
+
+
+

Supported Constructs

+

TODO

+
+
+

Limitations

+
+

Signal Values and Resolution

+

There are several cases where the behaviour of the translated VHDL deviates +from the source Verilog:

+
    +
  • The result of division by zero is x in Verilog but raises an exception in +VHDL.

  • +
  • Similarly, the result of reading past the end of an array in Verilog is x, +whereas VHDL raises an exception.

  • +
  • Any signal that is driven by two or more processes will have the value +‘U’. This is the result of the signal resolution function in the +std_logic_1164 package.

  • +
+
+
+

Constructs Not Supported

+

The following Verilog constructs cannot be translated to VHDL:

+
    +
  • fork and join

  • +
  • force and release

  • +
  • disable

  • +
  • real-valued variables

  • +
  • switches

  • +
  • hierarchical dereferencing

  • +
+
+
+

Other Limitations

+
    +
  • The test expressions in case statements must be constant.

  • +
  • Translation of a parameter to a corresponding VHDL generic +declaration. Instead the default parameter value is used.

  • +
+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/targets/tgt-vlog95.html b/targets/tgt-vlog95.html new file mode 100644 index 0000000000..bd6eb6586f --- /dev/null +++ b/targets/tgt-vlog95.html @@ -0,0 +1,204 @@ + + + + + + + + + The Verilog ‘95 Code Generator (-tvlog95) — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

The Verilog ‘95 Code Generator (-tvlog95)

+

Icarus Verilog contains a code generator to emit 1995 compliant Verilog from +the input Verilog netlist. This allows Icarus Verilog to function as a Verilog +> 1995 to Verilog 1995 translator. The main goal of the project was to convert +@*, ANSI style arguments and other constructs to something allowed in 1995 +Verilog.

+
+

Invocation

+

To translate a Verilog program to 1995 compliant Verilog, invoke “iverilog” +with the -tvlog95 flag:

+
% iverilog -tvlog95 -o my_design_95.v my_design.v
+
+
+

The generated Verilog will be placed in a single file (a.out by default), even +if the input Verilog is spread over multiple files.

+
+
+

Generator Flags

+
    +
  • -pspacing=N

    +

    Set the indent spacing (the default is 2).

    +
  • +
  • -pallowsigned=1

    +

    Allow emitting the various signed constructs as an extension to 1995 Verilog +(off by default).

    +
  • +
  • -pfileline=1

    +

    Emit the original file and line information as a comment for each generated +line (off by default).

    +
  • +
+
+
+

Structures that cannot be converted to 1995 compatible Verilog

+

The following Verilog constructs are not translatable to 1995 compatible Verilog:

+
    +
  • Automatic tasks or functions.

  • +
  • The power operator (**). Expressions of the form (2**N)**<variable> (where N +is a constant) can be converter to a shift.

  • +
  • Some System Verilog constructs (e.g. final blocks, ++/– operators, +etc.). 2-state variables are converted to 4-state variables.

  • +
+

Icarus extensions that cannot be translated:

+
    +
  • Integer constants greater than 32 bits.

  • +
  • Real valued nets.

  • +
  • Real modulus.

  • +
  • Most Verilog-A constructs.

  • +
+
+
+

Known Issues and Limitations

+

Some things are just not finished and should generate an appropriate +warning. Here is a list of the major things that still need to be looked at.

+
    +
  • There are still a few module instantiation port issues (pr1723367 and +partselsynth).

  • +
  • inout ports are not converted (tran-VP).

  • +
  • Variable selects of a non-zero based vector in a continuous assignment are +not converted.

  • +
  • There is no support for translating a zero repeat in a continuous +assignment. It is currently just dropped.

  • +
  • A pull device connected to a signal select is not translated correctly (this +may be fixed).

  • +
  • L-value indexed part selects with a constant undefined base in a continuous +assignment are not translated.

  • +
  • Logic gates are not arrayed exactly the same as the input and the instance +name is not always the same.

  • +
  • The signed support does not generate $signed() or $unsigned() function calls +in a continuous assignment expression.

  • +
  • The special power operator cases are not converted in a continuous +assignment.

  • +
  • Currently a signed constant that sets the MSB in an unsigned context will be +displayed as a negative value (e.g. bit = 1 translates to bit = -1).

  • +
  • Can net arrays, etc. be unrolled?

  • +
  • Can generate blocks be converted?

  • +
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/targets/tgt-vvp.html b/targets/tgt-vvp.html new file mode 100644 index 0000000000..ef0f4c9673 --- /dev/null +++ b/targets/tgt-vvp.html @@ -0,0 +1,181 @@ + + + + + + + + + The vvp Code Generator (-tvvp) — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

The vvp Code Generator (-tvvp)

+

The vvp target generates code for the “vvp” run time. This is the most +commonly used target for Icarus Verilog, as it is the main simulation engine.

+

Example command:

+
%  iverilog -o top.vvp -s top hello_world.v
+
+
+

Equivalent command:

+
%  iverilog -o top.vvp -tvvp -s top hello_world.v
+
+
+

With this example code in hello_world.v:

+
module top;
+    initial $display("Hello World!");
+endmodule
+
+
+

The resulting top.vvp will contain something similar to:

+
#! /usr/local/bin/vvp
+:ivl_version "13.0 (devel)" "(s20221226-119-g8cb2e1a05-dirty)";
+:ivl_delay_selection "TYPICAL";
+:vpi_time_precision + 0;
+:vpi_module "/usr/local/lib/ivl/system.vpi";
+:vpi_module "/usr/local/lib/ivl/vhdl_sys.vpi";
+:vpi_module "/usr/local/lib/ivl/vhdl_textio.vpi";
+:vpi_module "/usr/local/lib/ivl/v2005_math.vpi";
+:vpi_module "/usr/local/lib/ivl/va_math.vpi";
+S_0x563c3c5d1540 .scope module, "top" "top" 2 1;
+ .timescale 0 0;
+    .scope S_0x563c3c5d1540;
+T_0 ;
+    %vpi_call 2 2 "$display", "Hello World!" {0 0 0};
+    %end;
+    .thread T_0;
+# The file index is used to find the file name in the following table.
+:file_names 3;
+    "N/A";
+    "<interactive>";
+    "hello_world.v";
+
+
+

The first line contains the shebang. If this file is executed, the shebang tells the shell to use vvp for the execution of this file.

+

To run the simulation, execute:

+
%  ./top.vvp
+
+
+

Or you can call vvp directly:

+
%  vvp top.vvp
+
+
+

Next are some directives. The first one, :ivl_version specifies which version of iverilog this file was created with. Next is the delay selection with “min:typical:max” values and the time precision, which we did not set specifically, so the default value is used. The next lines tell vvp which VPI modules to load and in which order. The next lines tell vvp which VPI modules to load and in what order. Next, a new scope is created with the .scope directive and the timescale is set with .timescale. A thread T_0 is created that contains two instructions: %vpi_call executes the VPI function $display with the specified arguments, and %end terminates the simulation.

+
+

Opcodes

+

The various available opcodes can be seen in Opcodes

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/command_files.html b/usage/command_files.html new file mode 100644 index 0000000000..4f5104244c --- /dev/null +++ b/usage/command_files.html @@ -0,0 +1,304 @@ + + + + + + + + + Command File Format — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Command File Format

+

The basic format of a command file is one source file or compiler argument per +line. Command files may also have comments of various form, and options for +controlling the compiler.

+
+

Comments

+

Lines that start with a “#” character are comments. All text after the “#” +character, is ignored.

+

The “//” character sequence also starts a comment that continues to the end of +the line.

+

The “/*” and “*/” character sequences surround multi-line comments. All the +text between the comment start and comment end sequences is ignored, even when +that text spans multiple lines. This style of comment does not nest, so a “/*” +sequence within a multi-line comment is probably an error.

+
+
+

Plus-args

+

Outside of comments, lines that start with a “+” character are compiler +arguments. These are called plusargs but they are not the same as extended +arguments passed to the “vvp” command. The supported plusargs are definitively +listed in the iverilog manual page.

+

The plusargs lines are generally “+<name>+…” where the name is the name of +an switch, and the arguments are separated by “+” characters, as in:

+
+libext+.v+.V+.ver
+
+
+

With plusargs lines, the “+” character separates tokens, and not white space, +so arguments, which may include file paths, may include spaces. A plusarg line +is terminated by the line end.

+

The line in the command file may also be a “-y” argument. This works exactly +the same as the:

+
-y <path>
+
+
+

argument to the compiler; it declares a library directory. The “-y” syntax is +also a shorthand for the “+libdir” plusarg, which is a more general form:

+
+libdir+<path>...
+
+
+
+
+

File Names

+

Any lines that are not comments, compiler arguments or plusargs are taken by +the compiler to be a source file. The path can contain any characters (other +then comment sequences) including blanks, although leading and trailing white +space characters are stripped. The restriction of one file name per line is in +support of operating systems that can name files any which way. It is not +appropriate to expect white spaces to separate file names.

+
+
+

Variable Substitution

+

The syntax “$(name)” is a variable reference, and may be used anywhere within +filenames or directory names. The contents of the variable are read from the +environment and substituted in place of the variable reference. In Windows, +these environment variables are the very same variables that are set through +the Control Panel->System dialog box, and in UNIX these variables are +environment variables as exported by your shell.

+

Variables are useful for giving command files some installation +independence. For example, one can import a vendor library with the line:

+
-y $(VENDOR)/verilog/library
+
+
+

in the command file, and the next programmer will be able to use this command +file without editing it to point to the location of VENDOR on his +machine. Note the use of forward slashes as a directory separator. This works +even under Windows, so always use forward slashes in file paths and Windows +and UNIX users will be able to share command files.

+
+
+

An Example

+

This sample:

+
# This is a comment in a command file.
+# The -y statement declares a library
+# search directory
+-y $(PROJ_LIBRARY)/prims
+#
+# This plusarg tells the compiler that
+# files in libraries may have .v or .vl
+# extensions.
++libext+.v+.vl
+#
+main.v // This is a source file
+#
+# This is a file name with blanks.
+C:/Project Directory/file name.vl
+
+
+

is a command file that demonstrates the major syntactic elements of command +files. It demonstrates the use of comments, variables, plusargs and file +names. It contains a lot of information about the hypothetical project, and +suggests that command files can be used to describe the project as a whole +fairly concisely.

+

The syntax of command files is rich enough that they can be used to document +and control the assembly and compilation of large Verilog programs. It is not +unusual to have command files that are hundreds of lines long, although +judicious use of libraries can lead to very short command files even for large +designs. It is also practical to have different command files that pull +together combinations of sources and compiler arguments to make different +designs from the same Verilog source files.

+
+
+

Summary

+

Given the above description of the command file format, the following is a +list of the special records with their meaning.

+
    +
  • +libdir+*dir-path*

    +

    Specify directories to be searched for library modules. The dir-path can +have multiple directories, separated by “+” characters.

    +
  • +
  • +libdir-nocase+dir-path

    +

    This is the same as “+libdir+”, but when searching “nocase” libraries for +module files, case will not be taken as significant. This is useful when the +library is on a case insensitive file system.

    +
  • +
  • +libext+*suffix-string*

    +

    Declare the suffix strings to use when searching library directories for +Verilog files. The compiler may test a list of suffix strings to support a +variety of naming conventions.

    +
  • +
  • -y dir-path

    +

    This is like “+libdir+” but each line takes only one path. Like “+libdir+” +there can be multiple “-y” records to declare multiple library +directories. This is similar to the “-y” flag on the iverilog command line.

    +
  • +
  • -v file-name or -l file-name

    +

    This declares a library file. A library file is just like any other Verilog +source file, except that modules declared within it are not implicitly +possible root modules.

    +

    NOTE: The “-l” alias is new as of 2 October 2016. It will become available +in releases and snapshots made after that date.

    +
  • +
  • +incdir+*include-dir-path*

    +

    Declare a directory or list of directories to search for files included by +the “include” compiler directive. The directories are searched in +order. This is similar to the “-I” flag on the iverilog command line.

    +
  • +
  • +define+*name=value*

    +

    Define the preprocessor symbol “name” to have the string value “value”. If +the value (and the “=”) are omitted, then it is assumed to be the string +“1”. This is similar to the “-D” on the iverilog command line.

    +
  • +
  • +timescale+*units/precision*

    +

    Define the default timescale. This is the timescale that is used if there is +no other timescale directive in the Verilog source. The compiler default +default is “+timescale+1s/1s”, which this command file setting can +change. The format of the units/precision is the same as that for the +timescale directive in the verilog source.

    +
  • +
  • +toupper-filename

    +

    This token causes file names after this in the command file to be translated +to uppercase. this helps with situations where a directory has passed +through a DOS machine (or a FAT file system) and in the process the file +names become munged. This is not meant to be used in general, but only in +emergencies.

    +
  • +
  • +tolower-filename

    +

    The is the lowercase version of “+toupper-filename”.

    +
  • +
  • +parameter+*name=value*

    +

    This token causes the compiler to override a parameter value for a top-level +module. For example, if the module main has the parameter WIDTH, set the +width like this “+parameter+main.WIDTH=5”. Note the use of the complete +hierarchical name. This currently only works for parameters defined in root +(top level) modules and a defparam may override the command file value.

    +
  • +
  • +vhdl-work+*path*

    +

    When compiling VHDL, this token allows control over the directory to use for +holding working package declarations. For example, “+vhdl-work+workdir” will +cause the directory “workdir” to be used as a directory for holding working +working copies of package headers.

    +
  • +
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/command_line_flags.html b/usage/command_line_flags.html new file mode 100644 index 0000000000..4a395ad8b1 --- /dev/null +++ b/usage/command_line_flags.html @@ -0,0 +1,512 @@ + + + + + + + + + iverilog Command Line Flags — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

iverilog Command Line Flags

+

The iverilog command is the compiler/driver that takes the Verilog input and +generates the output format, whether the simulation file or synthesis +results. This information is at least summarized in the iverilog man page +distributed in typical installations, but here we try to include more detail.

+
+

General

+

These flags affect the general behavior of the compiler.

+
    +
  • -c <cmdfile>

    +

    This flag selects the command file to use. The command file is an +alternative to writing a long command line with a lot of file names and +compiler flags. See the Command File Format page for more information.

    +
  • +
  • -d <flag>

    +

    Enable compiler debug output. These are aids for debugging Icarus Verilog, +and this flag is not commonly used. +The flag is one of these debug classes:

    +
      +
    • scope

    • +
    • eval_tree

    • +
    • elaborate

    • +
    • synth2

    • +
    +
  • +
  • -g <generation flag> +the generation is the compiler language, and specifies the language and +extensions to use during the compile. The language level can be selected +by a major level selector, and by controlling various features. Various +“-g” flags can be compined. For example, to get Verilog 2001 without +specify supoprt, use “-g2001 -gno-specify”.

    +

    The supported flags are:

    +
      +
    • 1995

      +

      This flag enables the IEEE1364-1995 standard.

      +
    • +
    • 2001

      +

      This flag enables the IEEE1364-2001 standard.

      +
    • +
    • 2001-noconfig

      +

      This flag enables the IEEE1364-2001 standard with config file support +disabled. This eliminates the config file keywords from the language and +so helps some programs written to older 2001 support compile.

      +
    • +
    • 2005 +This flag enables the IEEE1364-2005 standard. This is default enabled +after v0.9.

    • +
    • 2009 +This flag enables the IEEE1800-2009 standard, which includes +SystemVerilog. The SystemVerilog support is not present in v0.9 and +earlier. It is new to git master as of November 2009. Actual SystemVerilog +support is ongoing.

    • +
    • 2012

      +

      This flag enables the IEEE1800-2012 standard, which includes +SystemVerilog.

      +
    • +
    • verilog-ams

      +

      This flag enables Verilog-AMS features that are supported by Icarus +Verilog. (This is new as of 5 May 2008.)

      +
    • +
    • assertions/supported-assertions/no-assertions

      +

      Enable or disable SystemVerilog assertions. When enabled, assertion +statements are elaborated. When disabled, assertion statements are parsed +but ignored. The supported-assertions option only enables assertions that +are currently supported by the compiler.

      +
    • +
    • specify/no-specify

      +

      Enable or disable support for specify block timing controls. When +disabled, specify blocks are parsed but ignored. When enabled, specify +blocks cause timing path and timing checks to be active.

      +
    • +
    • std-include/no-std-include

      +

      Enable or disable the search of a standard installation include directory +after all other explicit include directories. This standard include +directory is a convenient place to install standard header files that a +Verilog program may include.

      +
    • +
    • relative-include/no-relative-include

      +

      Enable or disable adding the local files directory to the beginning of the +include file search path. This allows files to be included relative to the +current file.

      +
    • +
    • xtypes/no-xtypes

      +

      Enable or disable support for extended types. Enabling types allows for +new types and type syntax that are Icarus Verilog extensions.

      +
    • +
    • io-range-error/no-io-range-error

      +

      When enabled the range for a port and any associated net declaration must +match exactly. When disabled a scalar port is allowed to have a net +declaration with a range (obsolete usage). A warning message will be +printed for this combination. All other permutations are still considered +an error.

      +
    • +
    • strict-ca-eval/no-strict-ca-eval

      +

      The standard requires that if any input to a continuous assignment +expression changes value, the entire expression is re-evaluated. By +default, parts of the expression that do not depend on the changed input +value(s) are not re-evaluated. If an expression contains a call to a +function that doesn’t depend solely on its input values or that has side +effects, the resulting behavior will differ from that required by the +standard. Enabling strict-ca-eval will force standard compliant behavior +(with some loss in performance).

      +
    • +
    • strict-expr-width/no-strict-expr-width

      +

      Enable or disable strict compliance with the standard rules for +determining expression bit lengths. When disabled, the RHS of a parameter +assignment is evaluated as a lossless expression, as is any expression +containing an unsized constant number, and unsized constant numbers are +not truncated to integer width.

      +
    • +
    • shared-loop-index/no-shared-loop-index

      +

      Enable or disable the exclusion of for-loop control variables from +implicit event_expression lists. When enabled, if a for-loop control +variable (loop index) is only used inside the for-loop statement, the +compiler will not include it in an implicit event_expression list it +calculates for that statement or any enclosing statement. This allows the +same control variable to be used in multiple processes without risk of +entering an infinite loop caused by each process triggering all other +processes that use the same variable. For strict compliance with the +standards, this behaviour should be disabled.

      +
    • +
    +
  • +
  • -i

    +

    Ignore missing modules. Normally it is an error if a module instantiation +refers to an undefined module. This option causes the compiler to skip over +that instantiation. It will also stop the compiler returning an error if +there are no top level modules. This allows the compiler to be used to check +incomplete designs for errors.

    +

    NOTE: The “-i” flag was added in v11.0.

    +
  • +
  • -L <path>

    +

    Add the specified directory to the path list used to locate VPI modules. The +default path includes only the install directory for the system.vpi module, +but this flag can add other directories. Multiple paths are allowed, and the +paths will be searched in order.

    +

    NOTE: The “-L” flag was added in v11.0.

    +
  • +
  • -l <path>

    +

    Add the specified file to the list of source files to be compiled, but mark +it as a library file. All modules contained within that file will be treated +as library modules, and only elaborated if they are instantiated by other +modules in the design.

    +

    NOTE: The “-l” flag is new as of 2 October 2016. It will become available in +releases and snapshots made after that date.

    +
  • +
  • -M<mode>=<path>

    +

    Write into the file specified by path a list of files that contribute to the +compilation of the design.

    +

    If _mode_ is all or prefix, this includes files that are included by +include directives and files that are automatically loaded by library +support as well as the files explicitly specified by the user.

    +

    If _mode_ is include, only files that are included by include directives +are listed.

    +

    If _mode_ is module, only files that are specified by the user or that are +automatically loaded by library support are listed. The output is one file +name per line, with no leading or trailing space.

    +

    If _mode_ is prefix, files that are included by include directives are +prefixed by “I ” and other files are prefixed by “M “.

    +
  • +
  • -m<module>

    +

    Add this module to the list of VPI modules to be loaded by the +simulation. Many modules can be specified, and all will be loaded, in the +order specified. The system module is implicit and always included (and +loaded last).

    +

    If the specified name includes at least one directory character, it is +assumed to be prefixed by the path to the module, otherwise the module is +searched for in the paths specified by preceding -L options, and if not +found there, in the iverilog base directory.

    +

    NOTE: The “-m” flag was added in v11.0.

    +
  • +
  • -o <path>

    +

    Specify the output file. The <path> is the name of the file to hold the +output. The default is “a.out”.

    +
  • +
  • -S

    +

    Activate synthesis. This flag tells the compiler to do what synthesis it can +do before calling the code generator. This flag is rarely used explicitly, +and certain code generators will implicitly enable this flag.

    +
  • +
  • -u

    +

    Treat each source file as a separate compilation unit (as defined in +SystemVerilog). If compiling for an IEEE1364 generation, this will just +reset all compiler directives (including macro definitions) before each new +file is processed.

    +

    NOTE: The “-u” flag was added in v11.0.

    +
  • +
  • -v

    +

    Be verbose. Print copyright information, progress messages, and some timing +information about various compilation phases.

    +

    (New in snapshots after 2014-12-16) If the selected target is vvp, the -v +switch is appended to the shebang line in the compiler output file, so +directly executing the compiler output file will turn on verbose messages in +vvp. This extra verbosity can be avoided by using the vvp command to +indirectly execute the compiler output file.

    +
  • +
  • -V

    +

    Print the version information. This skips all compilation. Just print the +version information, including version details for the various components of +the compiler.

    +
  • +
  • -R

    +

    Print the runtime paths of the compiler. This can be useful to find, e.g., +the include path of vpi_user.h.

    +
  • +
  • -W<warning class>

    +

    Enable/disable warnings. All the warning types (other then “all”) can be +prefixed with no- to disable that warning.

    +
      +
    • all

      +

      This enables almost all of the available warnings. More specifically, it +enables these warnings:

      +
      -Wanachronisms
      +-Wimplicit
      +-Wimplicit-dimensions
      +-Wmacro-replacement
      +-Wportbind
      +-Wselect-range
      +-Wtimescale
      +-Wsensitivity-entire-array
      +
      +
      +
    • +
    • anachronisms

      +

      This enables warnings for use of features that have been deprecated or +removed in the selected generation of the Verilog language.

      +
    • +
    • implicit

      +

      This enables warnings for creation of implicit declarations. For example, +if a scalar wire X is used but not declared in the Verilog source, this +will print a warning at its first use.

      +
    • +
    • implicit-dimensions

      +

      This enables warnings for the case where a port declaration or a var/net +declaration for the same name is missing dimensions. Normally, Verilog +allows you to do this (the undecorated declaration gets its dimensions +form the decorated declaration) but this is no longer common, and some +other tools (notable Xilix synthesizers) do not handle this correctly.

      +

      This flag is supported in release 10.1 or master branch snapshots after +2016-02-06.

      +
    • +
    • macro-redefinition

      +

      This enables warnings when a macro is redefined, even if the macro text +remains the same.

      +

      NOTE: The “macro-redefinition” flag was added in v11.0.

      +
    • +
    • macro-replacement

      +

      This enables warnings when a macro is redefined and the macro text +changes. Use no-macro-redefinition to disable this,

      +

      NOTE: The “macro-replacement” flag was added in v11.0.

      +
    • +
    • portbind

      +

      This enables warnings for ports of module instantiations that are not +connected properly, but probably should be. Dangling input ports, for +example, will generate a warning.

      +
    • +
    • select-range

      +

      This enables warnings for constant out-of-bound selects. This includes +partial or fully out-of-bound select as well as a select containing a ‘bx +or ‘bz in the index.

      +
    • +
    • timescale

      +

      This enables warnings for inconsistent use of the timescale directive. It +detects if some modules have no timescale, or if modules inherit timescale +from another file. Both probably mean that timescales are inconsistent, +and simulation timing can be confusing and dependent on compilation order.

      +
    • +
    • infloop

      +

      This enables warnings for always statements that may have runtime infinite +loops (i.e. has paths with zero or no delay). This class of warnings is +not included in -Wall and hence does not have a no- variant. A fatal error +message will always be printed when the compiler can determine that there +will definitely be an infinite loop (all paths have no or zero delay).

      +

      When you suspect an always statement is producing a runtine infinite loop, +use this flag to find the always statements that need to have their logic +verified. it is expected that many of the warnings will be false +positives, since the code treats the value of all variables and signals as +indeterninite.

      +
    • +
    • sensitivity-entire-vector

      +

      This enables warnings for when a part select with an “always @*” statement +results in the entire vector being added to the implicit sensitivity +list. Although this behavior is prescribed by the IEEE standard, it is not +what might be expected and can have performance implications if the vector +is large.

      +
    • +
    • sensitivity-entire-array

      +

      This enables warnings for when a word select with an “always @*” statement +results in the entire array being added to the implicit sensitivity +list. Although this behavior is prescribed by the IEEE standard, it is not +what might be expected and can have performance implications if the array +is large.

      +
    • +
    • floating-nets

      +

      This enables warnings for nets that are present but have no drivers.

      +

      This flag was added in version 11.0 or later (and is in the master branch +as of 2015-10-01).

      +
    • +
    +
  • +
  • -y<libdir>

    +

    Append the directory to the library module search path. When the compiler +finds an undefined module, it looks in these directories for files with the +right name.

    +
  • +
  • -Y<suf>

    +

    Appends suf to the list of file extensions that are used to resolve an +undefined module to a file name. Should be specified before any -y flag. For +example, this command:

    +
    % iverilog -Y .sv -y sources src.v
    +
    +
    +

    will try to resolve any undefined module m by looking into the directory +sources and checking if there exist files named m.v or m.sv.

    +
  • +
+
+
+

Preprocessor Flags

+

These flags control the behavior of the preprocessor. They are similar to +flags for the typical “C” compiler, so C programmers will find them familiar.

+
    +
  • -E

    +

    This flag is special in that it tells the compiler to only run the +preprocessor. This is useful for example as a way to resolve preprocessing +for other tools. For example, this command:

    +
    % iverilog -E -ofoo.v -DKEY=10 src1.v src2.v
    +
    +
    +

    runs the preprocessor on the source files src1.v and src2.v and produces the +single output file foo.v that has all the preprocessing (including header +includes and ifdefs) processed.

    +
  • +
  • -D<macro>

    +

    Assign a value to the macro name. The format of this flag is one of:

    +
    -Dkey=value
    +-Dkey
    +
    +
    +

    The key is defined to have the given value. If no value is given, then it is +assumed to be “1”. The above examples are the same as these defines in +Verilog source:

    +
    `define key value
    +`define key
    +
    +
    +
  • +
  • -I<path>

    +

    Append directory <path> to list of directories searched for Verilog include +files. The -I switch may be used many times to specify several directories +to search, the directories are searched in the order they appear on the +command line.

    +
  • +
+
+
+

Elaboration Flags

+

These are flags that pass information to the elaboration steps.

+
    +
  • -P<symbol>=<value>

    +

    Define a parameter using the defparam behavior to override a parameter +values. This can only be used for parameters of root module instances.

    +
  • +
  • -s <topmodule>

    +

    Specify the top level module to elaborate. Icarus Verilog will by default +choose modules that are not instantiated in any other modules, but sometimes +that is not sufficient, or instantiates too many modules. If the user +specifies one or more root modules with “-s” flags, then they will be used +as root modules instead.

    +
  • +
  • -Tmin, -Ttyp, -Tmax

    +

    Select the timings to use. The Verilog language allows many timings to be +specified as three numbers, min:typical:max, but for simulation you need to +choose which set to use. The “-Tmin” flag tells the compiler to at +elaboration time choose “min” times. The default is “-Ttyp”.

    +
  • +
+
+
+

Target Flags

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/getting_started.html b/usage/getting_started.html new file mode 100644 index 0000000000..d6e8a2f5de --- /dev/null +++ b/usage/getting_started.html @@ -0,0 +1,281 @@ + + + + + + + + + Getting Started With Icarus Verilog — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Getting Started With Icarus Verilog

+

Before getting started with actual examples, here are a few notes on +conventions. First, command lines and sequences take the same arguments on all +supported operating environments, including Linux, Windows and the various +Unix systems. When an example command is shown in a figure, the generic prompt +character “% ” takes the place of whatever prompt string is appropriate for +your system. Under Windows, the commands are invoked in a command window.

+

Second, when creating a file to hold Verilog code, it is common to use the +“.v” or the “.vl” suffix. This is not a requirement imposed by Icarus Verilog, +but a useful convention. Some people also use the suffixes “.ver” or even +“.vlg”. Examples in this book will use the “.v” suffix.

+

So let us start. Given that you are going to use Icarus Verilog as part of +your design process, the first thing to do as a designer is learn how to +compile and execute even the most trivial design. For the purposes of +simulation, we use as our example the most trivial simulation, a simple Hello, +World program.

+
module hello;
+  initial
+    begin
+      $display("Hello, World");
+      $finish ;
+    end
+endmodule
+
+
+

Use a text editor to place the program in a text file, hello.v, then compile +this program with the command:

+
% iverilog -o hello hello.v
+
+
+

The results of this compile are placed into the file “hello”, because the “-o” +flag tells the compiler where to place the compiled result. Next, execute the +compiled program like so:

+
% vvp hello
+Hello, World
+
+
+

And there it is, the program has been executed. So what happened? The first +step, the “iverilog” command, read and interpreted the source file, then +generated a compiled result. The compiled form may be selected by command line +switches, but the default is the “vvp” format, which is actually run later, as +needed. The “vvp” command of the second step interpreted the “hello” file from +the first step, causing the program to execute.

+

The “iverilog” and “vvp” commands are the most important commands available to +users of Icarus Verilog. The “iverilog” command is the compiler, and the “vvp” +command is the simulation runtime engine. What sort of output the compiler +actually creates is controlled by command line switches, but normally it +produces output in the default vvp format, which is in turn executed by the +vvp program.

+

As designs get larger and more complex, they gain hierarchy in the form of +modules that are instantiated within others, and it becomes convenient to +organize them into multiple files. A common convention is to write one +moderate sized module per file (or group related tiny modules into a single +file) then combine the files of the design together during compilation. For +example, the counter model in counter.v

+
module counter(out, clk, reset);
+
+  parameter WIDTH = 8;
+
+  output [WIDTH-1 : 0] out;
+  input              clk, reset;
+
+  reg [WIDTH-1 : 0]   out;
+  wire               clk, reset;
+
+  always @(posedge clk or posedge reset)
+    if (reset)
+      out <= 0;
+    else
+      out <= out + 1;
+
+endmodule // counter
+
+
+

and the test bench in counter_tb.v

+
module test;
+
+  /* Make a reset that pulses once. */
+  reg reset = 0;
+  initial begin
+     # 17 reset = 1;
+     # 11 reset = 0;
+     # 29 reset = 1;
+     # 11 reset = 0;
+     # 100 $stop;
+  end
+
+  /* Make a regular pulsing clock. */
+  reg clk = 0;
+  always #5 clk = !clk;
+
+  wire [7:0] value;
+  counter c1 (value, clk, reset);
+
+  initial
+     $monitor("At time %t, value = %h (%0d)",
+              $time, value, value);
+endmodule // test
+
+
+

are written into different files.

+

The “iverilog” command supports multi-file designs by two methods. The +simplest is to list the files on the command line:

+
% iverilog -o my_design  counter_tb.v counter.v
+% vvp my_design
+
+
+

This command compiles the design, which is spread across two input files, and +generates the compiled result into the “my_design” file. This works for small +to medium sized designs, but gets cumbersome when there are lots of files.

+

Another technique is to use a commandfile, which lists the input files in a +text file. For example, create a text file called “file_list.txt” with the +files listed one per line:

+
counter.v
+counter_tb.v
+
+
+

Then compile and execute the design with a command like so:

+
% iverilog -o my_design -c file_list.txt
+% vvp my_design
+
+
+

The command file technique clearly supports much larger designs simply by +saving you the trouble of listing all the source files on the command +line. Name the files that are part of the design in the command file and use +the “-c” flag to tell iverilog to read the command file as a list of Verilog +input files.

+

As designs get more complicated, they almost certainly contain many Verilog +modules that represent the hierarchy of your design. Typically, there is one +module that instantiates other modules but is not instantiated by any other +modules. This is called a root module. Icarus Verilog chooses as roots (There +can be more than one root) all the modules that are not instantiated by other +modules. If there are no such modules, the compiler will not be able to choose +any root, and the designer must use the “-sroot” switch to identify the root +module, like this:

+
% iverilog -s main -o hello hello.v
+
+
+

If there are multiple candidate roots, all of them will be elaborated. The +compiler will do this even if there are many root modules that you do not +intend to simulate, or that have no effect on the simulation. This can happen, +for example, if you include a source file that has multiple modules, but are +only really interested in some of them. The “-s” flag identifies a specific +root module and also turns off the automatic search for other root +modules. You can use this feature to prevent instantiation of unwanted roots.

+

As designs get even larger, they become spread across many dozens or even +hundreds of files. When designs are that complex, more advanced source code +management techniques become necessary. These are described in later chapters, +along with other advanced design management techniques supported by Icarus +Verilog.

+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/gtkwave.html b/usage/gtkwave.html new file mode 100644 index 0000000000..4637040354 --- /dev/null +++ b/usage/gtkwave.html @@ -0,0 +1,232 @@ + + + + + + + + + Waveforms With GTKWave — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Waveforms With GTKWave

+

GTKWave is a VCD waveform viewer based on the GTK library. This viewer support +VCD and LXT formats for signal dumps. GTKWAVE is available on github +here. Most Linux distributions already +include gtkwave prepackaged.

+../_images/GTKWave_Example2.png +

Generating VCD/FST files for GTKWAVE ———————————— +Waveform dumps are written by the Icarus Verilog runtime program vvp. The user +uses $dumpfile and $dumpvars system tasks to enable waveform dumping, then the +vvp runtime takes care of the rest. The output is written into the file +specified by the $dumpfile system task. If the $dumpfile call is absent, the +compiler will choose the file name dump.vcd or dump.lxt or dump.fst, depending +on runtime flags. The example below dumps everything in and below the test +module:

+
// Do this in your test bench
+
+initial
+begin
+   $dumpfile("test.vcd");
+   $dumpvars(0,test);
+end
+
+
+

By default, the vvp runtime will generate VCD dump output. This is the default +because it is the most portable. However, when using gtkwave, the FST output +format is faster and most compact. Use the “-fst” extended argument to +activate LXT output. For example, if your compiled output is written into the +file “foo.vvp”, the command:

+
% vvp foo.vvp -fst <other-plusargs>
+
+
+

will cause the dumpfile output to be written in FST format. Absent any +specific $dumpfile command, this file will be called dump.fst, which can be +viewed with the command:

+
% gtkwave dump.fst
+
+
+
+

A Working Example

+

First, the design itself:

+
module counter(out, clk, reset);
+
+  parameter WIDTH = 8;
+
+  output [WIDTH-1 : 0] out;
+  input            clk, reset;
+
+  reg [WIDTH-1 : 0]   out;
+  wire            clk, reset;
+
+  always @(posedge clk)
+    out <= out + 1;
+
+  always @reset
+    if (reset)
+      assign out = 0;
+    else
+      deassign out;
+
+endmodule // counter
+
+
+

Then the simulation file:

+
module test;
+
+  /* Make a reset that pulses once. */
+  reg reset = 0;
+  initial begin
+     $dumpfile("test.vcd");
+     $dumpvars(0,test);
+
+     # 17 reset = 1;
+     # 11 reset = 0;
+     # 29 reset = 1;
+     # 5  reset =0;
+     # 513 $finish;
+  end
+
+  /* Make a regular pulsing clock. */
+  reg clk = 0;
+  always #1 clk = !clk;
+
+  wire [7:0] value;
+  counter c1 (value, clk, reset);
+
+  initial
+     $monitor("At time %t, value = %h (%0d)",
+              $time, value, value);
+endmodule // test
+
+
+

Compile, run, and view waveforms with these commands:

+
% iverilog -o dsn counter_tb.v counter.v
+% vvp dsn
+% gtkwave test.vcd &
+
+
+

Click on the ‘test’, then ‘c1’ in the top left box on GTKWAVE, then drag the +signals to the Signals box. You will be able to add signals to display, +scanning by scope.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/icarus_verilog_extensions.html b/usage/icarus_verilog_extensions.html new file mode 100644 index 0000000000..d87a4a3650 --- /dev/null +++ b/usage/icarus_verilog_extensions.html @@ -0,0 +1,210 @@ + + + + + + + + + Icarus Verilog Extensions — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Icarus Verilog Extensions

+

Icarus Verilog supports certain extensions to the baseline IEEE 1364 +standard. Some of these are picked from extended variants of the +language, such as SystemVerilog, and some are expressions of internal +behavior of Icarus Verilog, made available as a tool debugging aid.

+
+

Built-in System Functions

+
+
+

Extended Verilog Data Types

+

This feature is turned on by the generation flag “-gxtypes” and turned +off by the generation flag “-gno-xtypes”. It is turned on by default.

+

Icarus Verilog adds support for extended data types. This extended +type syntax is based on a proposal by Cadence Design Systems, +originally as an update to the IEEE 1364 standard. Icarus Verilog +currently only takes the new primitive types from the proposal.

+

SystemVerilog provides the same functionality using somewhat different +syntax. This extension is maintained for backwards compatibility.

+
    +
  • Types

  • +
+

Extended data types separates the concept of net/variable from the +data type. Both nets and variables can declared with any data +type. The primitive types available are:

+
logic  - The familiar 0, 1, x and z, optionally with strength.
+bool   - Limited to only 0 and 1
+real   - 64-bit real values
+
+
+

Nets with logic type may have multiple drivers with strength, and the +value is resolved the usual way. Only logic values may be driven to +logic nets, so bool values driven onto logic nets are implicitly +converted to logic.

+

Nets with any other type may not have multiple drivers. The compiler +should detect the multiple drivers and report an error.

+
    +
  • Declarations

  • +
+

The declaration of a net is extended to include the type of the wire, +with the syntax:

+
wire <type> <wire-assignment-list>... ;
+
+
+

The <type>, if omitted, is taken to be logic. The “wire” can be any of +the net keywords. Wires can be logic, bool, real, or vectors of logic +or bool. Some valid examples:

+
wire real foo = 1.0;
+tri logic bus[31:0];
+wire bool addr[23:0];
+... and so on.
+
+
+

The declarations of variables is similar. The “reg” keyword is used to +specify that this is a variable. Variables can have the same data +types as nets.

+
    +
  • Ports

  • +
+

Module and task ports in standard Verilog are restricted to logic +types. This extension removes that restriction, allowing any of +the above types to pass through the port consistent with the +continuous assignment connectivity that is implied by the type.

+
    +
  • Expressions

  • +
+

Expressions in the face of real values is covered by the baseline +Verilog standard.

+

The bool type supports the same operators as the logic type, with the +obvious differences imposed by the limited domain.

+

Comparison operators (not case compare) return logic if either of +their operands is logic. If both are bool or real (including mix of +bool and real) then the result is bool. This is because comparison of +bools and reals always return exactly true or false.

+

Case comparison returns bool. This differs from baseline Verilog, +which strictly speaking returns a logic, but only 0 or 1 values.

+

Arithmetic operators return real if either of their operands is real, +otherwise they return logic if either of their operands is logic. If +both operands are bool, they return bool.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/icarus_verilog_quirks.html b/usage/icarus_verilog_quirks.html new file mode 100644 index 0000000000..2b8d2ae6fa --- /dev/null +++ b/usage/icarus_verilog_quirks.html @@ -0,0 +1,169 @@ + + + + + + + + + Icarus Verilog Quirks — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Icarus Verilog Quirks

+

This is a list of known quirks that are presented by Icarus Verilog. The idea +of this chapter is to call out ways that Icarus Verilog differs from the +standard, or from other implementations.

+

This is NOT AN EXHAUSTIVE LIST. If something is missing from this list, let us +know and we can add documentation.

+
+

System Tasks - Unique to Icarus Verilog

+

These are system tasks that are unique to Icarus Verilog. Don’t use any of +these if you want to keep your code portable across other Verilog compilers.

+
+

$readmempath

+

The “$readmemb” and “$readmemh” system tasks read text files that contain data +values to populate memories. Normally, those files are found in a current work +directory. The “$readmempath()” system task can be used to create a search +path for those files. For example:

+
reg [7:0] mem [0:7];
+initial begin
+  $readmemh("datafile.txt", mem);
+end
+
+
+

This assumes that the “datafile.txt” is in the current working directory where +the vvp command is running. But with the “$readmempath”, one can specify a +search path:

+
reg [7:0] mem [0:7];
+initial begin
+  $readmempath(".:alternative:/global/defaults");
+  $readmemh("datafile.txt", mem);
+end
+
+
+

In this example, the “datafile.txt” is searched for in each of the directories +in the above list (separated by “:” characters). The first located instance +is the one that is used. So for example, if “./datafile.txt” exists, then it +is read instead of “/global/defaults/datafile.txt” even if the latter exists.

+
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/index.html b/usage/index.html new file mode 100644 index 0000000000..abf48ca08d --- /dev/null +++ b/usage/index.html @@ -0,0 +1,151 @@ + + + + + + + + + Icarus Verilog Usage — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/usage/installation.html b/usage/installation.html new file mode 100644 index 0000000000..b4db515838 --- /dev/null +++ b/usage/installation.html @@ -0,0 +1,294 @@ + + + + + + + + + Installation Guide — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Installation Guide

+

Icarus Verilog may be installed from source code, or from pre-packaged binary +distributions. If you don’t have need for the very latest, and prepackaged +binaries are available, that would be the best place to start.

+
+

Installation From Source

+

Icarus is developed for Unix-like environments but can also be compiled on +Windows systems using the Cygwin environment or MinGW compilers. The following +instructions are the common steps for obtaining the Icarus Verilog source, +compiling and installing. Note that there are precompiled and/or prepackaged +versions for a variety of systems, so if you find an appropriate packaged +version, then that is the easiest way to install.

+

The source code for Icarus is stored under the git source code control +system. You can use git to get the latest development head or the latest of a +specific branch. Stable releases are placed on branches, and in particular v11 +stable releases are on the branch “v11-branch” To get the development version +of the code follow these steps:

+
% git config --global user.name "Your Name Goes Here"
+% git config --global user.email you@yourpublicemail.example.com
+% git clone https://github.com/steveicarus/iverilog.git
+
+
+

The first two lines are optional and are used to tell git who you are. This +information is important if/when you submit a patch. We suggest that you add +this information now so you don’t forget to do it later. The clone will create +a directory, named iverilog, containing the source tree, and will populate +that directory with the most current source from the HEAD of the repository.

+

Change into this directory using:

+
% cd iverilog
+
+
+

Normally, this is enough as you are now pointing at the most current +development code, and you have implicitly created a branch “master” that +tracks the development head. However, If you want to actually be working on +the v11-branch (the branch where the latest v11 patches are) then you checkout +that branch with the command:

+
% git checkout --track -b v11-branch origin/v11-branch
+
+
+

This creates a local branch that tracks the v11-branch in the repository, and +switches you over to your new v11-branch. The tracking is important as it +causes pulls from the repository to re-merge your local branch with the remote +v11-branch. You always work on a local branch, then merge only when you +push/pull from the remote repository.

+

Now that you’ve cloned the repository and optionally selected the branch you +want to work on, your local source tree may later be synced up with the +development source by using the git command:

+
% git pull
+
+
+

The git system remembers the repository that it was cloned from, so you don’t +need to re-enter it when you pull.

+

Finally, configuration files are built by the extra step:

+
% sh autoconf.sh
+
+
+

The source is then compiled as appropriate for your system. See the specific +build instructions below for your operation system for what to do next.

+

You will need autoconf and gperf installed in order for the script to work. +If you get errors such as:

+
Autoconf in root...
+autoconf.sh: 10: autoconf: not found
+Precompiling lexor_keyword.gperf
+autoconf.sh: 13: gperf: not found.
+
+
+

You will need to install download and install the autoconf and gperf tools.

+
+
+

Icarus Specific Configuration Options

+

Icarus takes many of the standard configuration options and those will not be +described here. The following are specific to Icarus:

+
--enable-suffix[=suffix]
+
+
+

This option allows the user to build Icarus with a default suffix or when +provided a user defined suffix. Older stable releases have this flag on by +default e.g.(V0.8 by default will build with a “-0.8” suffix). All versions +have an appropriate default suffix (“-<base_version>”).

+

All programs or directories are tagged with this suffix. e.g.(iverilog-0.8, +vvp-0.8, etc.). The output of iverilog will reference the correct run time +files and directories. The run time will check that it is running a file with +a compatible version e.g.(you can not run a V0.9 file with the V0.8 run +time).

+
--with-valgrind
+
+
+

This option adds extra memory cleanup code and pool management code to allow +better memory leak checking when valgrind is available. This option is not +need when checking for basic errors with valgrind.

+
--enable-libvvp
+
+
+

The vvp progam is built as a small stub linked to a shared library, +libvvp.so, that may be linked with other programs so that they can host +a vvp simulation.

+
+
+

Compiling on Linux/Unix

+

(Note: You will need to install bison, flex, g++ and gcc) This is probably the +easiest case. Given that you have the source tree from the above instructions, +the compile and install is generally as simple as:

+
% ./configure
+% make
+(su to root)
+# make install
+
+
+

The “make install” typically needs to be done as root so that it can install +in directories such as “/usr/local/bin” etc. You can change where you want to +install by passing a prefix to the “configure” command:

+
% ./configure --prefix=/my/special/directory
+
+
+

This will configure the source for eventual installation in the directory that +you specify. Note that “rpm” packages of binaries for Linux are typically +configured with “–prefix=/usr” per the Linux File System Standard.

+

Make sure you have the latest version of flex otherwise you will get an error +when parsing lexor.lex.

+
+
+

Compiling on Macintosh OS X

+

Since Mac OS X is a BSD flavor of Unix, you can install Icarus Verilog from +source using the procedure described above. You need to install the Xcode +software, which includes the C and C++ compilers for Mac OS X. The package is +available for free download from Apple’s developer site. Once Xcode is +installed, you can build Icarus Verilog in a terminal window just like any +other Unix install.

+

For versions newer than 10.3 the GNU Bison tool (packaged with Xcode) needs to +be updated to version 3.

+
brew install bison
+echo 'export PATH="/usr/local/opt/bison/bin:$PATH"' >> ~/.bash_profile
+
+
+

Icarus Verilog is also available through the Homebrew package manager: “brew +install icarus-verilog”.

+
+
+

Compiling for Windows

+

These are instructions for building Icarus Verilog binaries for +Windows using mingw cross compiler tools on Linux.

+

To start with, you need the mingw64-cross-* packages for your linux +distribution, which gives you the x86_64-w64-mingw32-* commands +installed on your system. Installing the cross environment is outside +the scope of this writeup.

+

First, configure with this command:

+
$ ./configure --host=x86_64-w64-mingw32
+
+
+

This generates the Makefiles needed to cross compile everything with +the mingw32 compiler. The configure script will generate the command +name paths, so long as commands line x86_64-w64-mingw32-gcc +et. al. are in your path.

+

Next, compile with the command:

+
$ make
+
+
+

The configure generated the cross compiler flags, but there are a few +bits that need to be compiled with the native compiler. (version.exe +for example is used by the build process but is not installed.) The +configure script should have gotten all that right.

+

There is also a MSYS2 build recipe which you can find under msys2/ in the repository.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/ivlpp_flags.html b/usage/ivlpp_flags.html new file mode 100644 index 0000000000..512f20484d --- /dev/null +++ b/usage/ivlpp_flags.html @@ -0,0 +1,285 @@ + + + + + + + + + IVLPP - IVL Preprocessor — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

IVLPP - IVL Preprocessor

+

The ivlpp command is a Verilog preprocessor that handles file +inclusion and macro substitution. The program runs separate from the +actual compiler so as to ease the task of the compiler proper, and +provides a means of preprocessing files off-line.

+

USAGE:

+
+

ivlpp [options] <file>

+
+

The <file> parameter is the name of the file to be read and +preprocessed. The resulting output is sent to standard output. The +valid options include:

+
    +
  • -Dname[=value]

    +
    +

    Predefine the symbol name to have the specified +value. If the value is not specified, then 1 is +used. This is mostly of use for controlling conditional +compilation.

    +

    This option does not override existing `define +directives in the source file.

    +
    +
  • +
  • +
    -F <path>
    +

    Read ivlpp options from a FLAGS FILE. This is not the same +as a file list. This file contains flags, not source +files. There may be multiple flags files.

    +
    +
    +
  • +
  • +
    -f <path>
    +

    Read ivlpp input files from a file list. There can be no +more than one file list.

    +
    +
    +
  • +
  • +
    -I <dir>
    +

    Add a directory to the include path. Normally, only “.” is +in the search path. The -I flag causes other directories +to be searched for a named file. There may be as many -I +flags as needed.

    +
    +
    +
  • +
  • +
    -L
    +

    Generate `line directives. The ivl compiler understands +these directives and uses them to keep track of the +current line of the original source file. This makes error +messages more meaningful.

    +
    +
    +
  • +
  • +
    -o <file>
    +

    Send the output to the named file, instead of to standard +output.

    +
    +
    +
  • +
  • +
    -v
    +

    Print version and copyright information before processing +input files.

    +
    +
    +
  • +
  • +
    -V
    +

    Print version and copyright information, then exit WITHOUT +processing any input files.

    +
    +
    +
  • +
+
+

Flags File

+

A flags file contains flags for use by ivlpp. This is a convenient way +for programs to pass complex sets of flags to the ivlpp program.

+

Blank lines and lines that start with “#” are ignored. The latter can +be used as comment lines. All other lines are flag lines. Leading and +trailing white space are removed before the lines are interpreted.

+

Other lines have the simple format:

+
<key>:<value>
+
+
+

The colon character separates a key from the value. The supported +keys, with their corresponding values, are:

+
    +
  • D:name=<value>

    +
    +

    This is exactly the same as the “-Dname=<value>” described above.

    +
    +
  • +
  • I:<dir>

    +
    +

    This is exactly the same as “-I<dir>”.

    +
    +
  • +
  • relative include:<flag>

    +
    +

    The <flag> can be “true” or “false”. This enables “relative +includes” nesting behavior.

    +
    +
  • +
  • vhdlpp:<path>

    +
    +

    Give the path to the vhdlpp program. This program is used to +process VHDL input files.

    +
    +
  • +
+
+
+

Locating Included Files

+

The ivlpp preprocessor implements the `include directives by +substituting the contents of the included file in place of the line +with the `include directive. The name that the programmer specifies is +a file name. Normally, the preprocessor looks in the current working +directory for the named file. However, the -I flags can be used to +specify a path of directories to search for named include files. The +current directory will be searched first, followed by all the include +directories in the order that the -I flag appears.

+

The exception to this process is include files that have a name that +starts with the ‘/’ character. These file names are rooted names +and must be in the rooted location specified.

+
+
+

Generated Line Directives

+

Compilers generally try to print along with their error messages the +file and line number where the error occurred. Icarus Verilog is no +exception. However, if a separate preprocessor is actually selecting +and opening files, then the line numbers counted by the compiler +proper will not reflect the actual line numbers in the source file.

+

To handle this situation, the preprocessor can generate line +directives. These directives are lines of the form:

+
`line <num> <name> <level>
+
+
+

where <name> is the file name in double-quotes and <num> is the line +number in the file. The parser changes the filename and line number +counters in such a way that the next line is line number <num> in +the file named <name>. For example:

+
`line 6 "foo.vl" 0
+// I am on line 6 in file foo.vl.
+
+
+

The preprocessor generates a `line directive every time it switches +files. That includes starting an included file (`line 1 “foo.vlh” 1) or +returning to the including file.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/reporting_issues.html b/usage/reporting_issues.html new file mode 100644 index 0000000000..af088737d1 --- /dev/null +++ b/usage/reporting_issues.html @@ -0,0 +1,193 @@ + + + + + + + + + Reporting Issues — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Reporting Issues

+

The developers of and contributers to Icarus Verilog use github to track +issues and to create patches for the product. If you believe you have found a +problem, use the Issues tracker at the +Icarus Verilog github page.

+

You may browse the bugs database for existing +bugs that may be related to yours. You might find that your bug has +already been fixed in a later release or snapshot. If that’s the case, +then you are set.

+

On the main page, you will find a row of selections near the top. Click the +Issues link to get to the +list of issues, open and closed. You will find a friendly green button where +you can create a new issue. You will be asked to create a title for your +issue, and to write a detailed description of your issue. Please include +enough information that anyone who sees your issue can understand and +reproduce it.

+
+

Good Issue Reporting

+

Before an error can be fixed, one needs to understand what the problem +is. Try to explain what is wrong and why you think it is wrong. Please +try to include sample code that demonstrates the problem.

+

One key characteristic of a well reported issue is a small sample program that +demonstrates the issue. The smaller the better. No developer wants to wade +through hundreds of lines of working Verilog to find the few lines that cause +trouble, so if you can get it down to a 10 line sample program, then your +issue will be far more likely to be addressed.

+

Also, include the command line you use to invoke the compiler. For +example:

+
iverilog -o foo.out -tvvp foo.v
+iverilog foo.vl -s starthere
+
+
+

Be prepared to have a conversation about your issue. More often then you would +expect, the issue turns out to be a bug in your program, and the person +looking into your issue may point out a bug in your code. You learn something, +and we all win. We are not always correct, though, so if we are incorrect, +help us see our error, if that’s appropriate. If we don’t understand what your +issue is, we will label your issue with a “Need info” label, and if we never +hear from you again, your issue may be closed summarily.

+

If you can submit a complete, working program that we can use in the +regression test suite, then that is the best. Check out the existing tests in +the regression test suite to see how they are structured. If you have a +complete test that can go into the test suite, then that saves everyone a lot +of grief, and again you increase the odds that your issue will be addressed.

+
+
+

How To Create A Pull Request

+

Bug reports with patches/PRs are very welcome. Please also add a new test case in the regression test suite to prevent the bug from reappearing.

+

If you are editing the source, you should be using the latest +version from git. Please see the developer documentation for more +detailed instructions – Getting Started as a Contributer .

+

COPYRIGHT ISSUES

+

Icarus Verilog is Copyright (c) 1998-2024 Stephen Williams except +where otherwise noted. Minor patches are covered as derivative works +(or editorial comment or whatever the appropriate legal term is) and +folded into the rest of ivl. However, if a submission can reasonably +be considered independently copyrightable, it’s yours and I encourage +you to claim it with appropriate copyright notices. This submission +then falls under the “otherwise noted” category.

+

I must insist that any copyright material submitted for inclusion +include the GPL license notice as shown in the rest of the source.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/simulation.html b/usage/simulation.html new file mode 100644 index 0000000000..282d937371 --- /dev/null +++ b/usage/simulation.html @@ -0,0 +1,581 @@ + + + + + + + + + Simulation Using Icarus Verilog — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Simulation Using Icarus Verilog

+

Simulation is the process of creating models that mimic the behavior of the +device you are designing (simulation models) and creating models to exercise +the device (test benches). The simulation model need not reflect any +understanding of the underlying technology, and the simulator need not know +that the design is intended for any specific technology.

+

The Verilog simulator, in fact, is usually a different program than the +synthesizer. It may even come from a different vendor. The simulator need not +know of or generate netlists for the target technology, so it is possible to +write one simulator that can be used to model designs intended for a wide +variety of technologies. A synthesizer, on the other hand, does need to know a +great deal about the target technology in order to generate efficient +netlists. Synthesizers are often technology specific and come from vendors +with specialized knowledge, whereas simulators are more general purpose.

+

Simulation models and test benches, therefore, can use the full range of +Verilog features to model the intended design as clearly as possible. This is +the time to test the algorithms of the design using language that is +relatively easy for humans to read. The simulator, along with the test bench, +can test that the clearly written model really does behave as intended, and +that the intended behavior really does meet expectations.

+

The test benches model the world outside the design, so they are rarely +destined for real hardware. They are written in Verilog simply as a matter of +convenience, and sometimes they are not written in Verilog at all. The test +benches are not throw-away code either, as they are used to retest the device +under test as it is transformed from a simulation model to a synthesizeable +description.

+
+

Compilation and Elaboration

+

Simulation of a design amounts to compiling and executing a program. The +Verilog source that represents the simulation model and the test bench is +compiled into an executable form and executed by a simulation +engine. Internally, Icarus Verilog divides the compilation of program source +to an executable form into several steps, and basic understanding of these +steps helps understand the nature of failures and errors. The first step is +macro preprocessing, then compilation, elaboration, optional optimizations and +finally code generation. The boundary between these steps is often blurred, +but this progression remains a useful model of the compilation process.

+

The macro preprocessing step performs textual substitutions of macros defined +with “`define” statements, textual inclusion with “`include” statements, and +conditional compilation by “`ifdef” and “`ifndef” statements. The +macropreprocessor for Icarus Verilog is internally a separate program that can +be accessed independently by using the “-E” flag to the “iverilog” command, +like so:

+
% iverilog -E -o out.v example.v
+
+
+

This command causes the input Verilog file “example.v” to be preprocessed, and +the output, a Verilog file without preprocessor statements, written into +“out.v”. The “`include” and “`ifdef” directives in the input file are interpreted, +and defined macros substituted, so that the output, a single file, is the same +Verilog but with the preprocessor directives gone. All the explicitly +specified source files are also combined by the preprocessor, so that the +preprocessed result is a single Verilog stream.

+

Normally, however, the “-E” flag is not used and the preprocessed Verilog is +instead sent directly to the next step, the compiler. The compiler core takes +as input preprocessed Verilog and generates an internal parsed form. The +parsed form is an internal representation of the Verilog source, in a format +convenient for further processing, and is not accessible to the user.

+

The next step, elaboration, takes the parsed form, chooses the root modules, +and instantiates (makes instances of) those roots. The root instances may +contain instances of other modules, which may in turn contain instances of yet +other modules. The elaboration process creates a hierarchy of module instances +that ends with primitive gates and statements.

+

Note that there is a difference between a module and a module instance. A +module is a type. It is a description of the contents of module instances that +have its type. When a module is instantiated within another module, the module +name identifies the type of the instance, and the instance name identifies the +specific instance of the module. There can be many instances of any given +module.

+

Root modules are a special case, in that the programmer does not give them +instance names. Instead, the instance names of root modules are the same as +the name of the module. This is valid because, due to the nature of the +Verilog syntax, a module can be a root module only once, so the module name +itself is a safe instance name.

+

Elaboration creates a hierarchy of scopes. Each module instance creates a new +scope within its parent module, with each root module starting a +hierarchy. Every module instance in the elaborated program has a unique scope +path, a hierarchical name, that starts with its root scope and ends with its +own instance name. Every named object, including variables, parameters, nets +and gates, also has a hierarchical name that starts with a root scope and ends +with its own base name. The compiler uses hierarchical names in error messages +generated during or after elaboration, so that erroneous items can be +completely identified. These hierarchical names are also used by waveform +viewers that display waveform output from simulations.

+

The elaboration process creates from the parsed form the scope hierarchy +including the primitive objects within each scope. The elaborated design then +is optimized to reduce it to a more optimal, but equivalent design. The +optimization step takes the fully elaborated design and transforms it to an +equivalent design that is smaller or more efficient. These optimizations are, +for example, forms of constant propagation and dead code elimination. Useless +logic is eliminated, and constant expressions are pre-calculated. The +resulting design behaves as if the optimizations were not performed, but is +smaller and more efficient. The elimination (and spontaneous creation) of +gates and statements only affects the programmer when writing VPI modules, +which through the API have limited access to the structures of the design.

+

Finally, the optimized design, which is still in an internal form not +accessible to users, is passed to a code generator that writes the design into +an executable form. For simulation, the code generator is selected to generate +the vvp format–a text format that can be executed by the simulation +engine. Other code generators may be selected by the Icarus Verilog user, even +third party code generators, but the vvp code generator is the default for +simulation purposes.

+
+
+

Making and Using Libraries

+

Although simple programs may be written into a single source file, this gets +inconvenient as the designs get larger. Also, writing the entire program into +a single file makes it difficult for different programs to share common +code. It therefore makes sense to divide large programs into several source +files, and to put generally useful source code files somewhere accessible to +multiple designs.

+

Once the program is divided into many files, the compiler needs to be told how +to find the files of the program. The simplest way to do that is to list the +source files on the command line or in a command file. This is for example the +best way to divide up and integrate test bench code with the simulation model +of the device under test.

+
+

The Macro Preprocessor

+

Another technique is to use the macro preprocessor to include library files +into a main file. The include directive takes the name of a source file to +include. The preprocessor inserts the entire contents of the included file in +place of the include directive. The preprocessor normally looks in the +current working directory (the current working directory of the running +compiler, and not the directory where the source file is located) for the +included file, but the “-I” switch to “iverilog” can add directories to the +search locations list.

+
% iverilog -I/directory/to/search example.v
+
+
+

It is common to create include directories shared by a set of programs. The +preprocessor include directive can be used by the individual programs to +include the source files that it needs.

+

The preprocessor method of placing source code into libraries is general +(arbitrary source code can be placed in the included files) but is static, in +the sense that the programmer must explicitly include the desired library +files. The automatic module library is a bit more constrained, but is +automatic.

+
+
+

Automatic Module Libraries

+

A common use for libraries is to store module definitions that may be of use +to a variety of programs. If modules are divided into a single module per +file, and the files are named appropriately, and the compiler is told where to +look, then the compiler can automatically locate library files when it finds +that a module definition is missing.

+

For this to work properly, the library files must be Verilog source, they +should contain a single module definition, and the files must be named after +the module they contain. For example, if the module “AND2” is a module in the +library, then it belongs in a file called “AND2.v” and that file contains only +the “AND2” module. A library, then, is a directory that contains properly +named and formatted source files.

+
% iverilog -y/library/to/search example.v
+
+
+

The “-y” flag to “iverilog” tells the compiler to look in the specified +directory for library modules whenever the program instantiates a module that +is not otherwise defined. The programmer may include several “-y” flags on the +command line (or in a command file) and the compiler will search each +directory in order until an appropriate library file is found to resolve the +module.

+

Once a module is defined, either in the program or by reading a library +module, the loaded definition is used from then on within the program. If the +module is defined within a program file or within an included file, then the +included definition is used instead of any library definition. If a module is +defined in multiple libraries, then the first definition that the compiler +finds is used, and later definitions are never read.

+

Icarus Verilog accesses automatic libraries during elaboration, after it has +already preprocessed and parsed the non-library source files. Modules in +libraries are not candidates for root modules, and are not even parsed unless +they are instantiated in other source files. However, a library module may +reference other library modules, and reading in a library module causes it to +be parsed and elaborated, and further library references resolved, just like a +non-library module. The library lookup and resolution process iterates until +all referenced modules are resolved, or known to be missing from the +libraries.

+

The automatic module library technique is useful for including vendor or +technology libraries into a program. Many EDA vendors offer module libraries +that are formatted appropriately; and with this technique, Icarus Verilog can +use them for simulation.

+
+
+
+

Advanced Command Files

+

Command files were mentioned in the “Getting Started” chapter, but only +briefly. In practice, Verilog programs quickly grow far beyond the usefulness +of simple command line options, and even the macro preprocessor lacks the +flexibility to combine source and library modules according to the advancing +development process.

+

The main contents of a command file is a list of Verilog source files. You can +name in a command file all the source files that make up your design. This is +a convenient way to collect together all the files that make up your +design. Compiling the design can then be reduced to a simple command line like +the following:

+
% iverilog -c example.cf
+
+
+

The command file describes a configuration. That is, it lists the specific +files that make up your design. It is reasonable, during the course of +development, to have a set of different but similar variations of your +design. These variations may have different source files but also many common +source files. A command file can be written for each variation, and each +command file lists the source file names used by each variation.

+

A configuration may also specify the use of libraries. For example, different +configurations may be implementations for different technologies so may use +different parts libraries. To make this work, command files may include “-y” +statements. These work in command files exactly how they work on “iverilog” +command line. Each “-y” flag is followed by a directory name, and the +directories are searched for library modules in the order that they are listed +in the command file.

+

The include search path can also be specified in configuration files with +“+incdir+” tokens. These tokens start with the “+incdir+” string, then +continue with directory paths, separated from each other with “+” characters +(not spaces) for the length of the line.

+

Other information can be included in the command file. See the section Command +File Format for complete details on what can go in a command file.

+
+
+

Input Data at Runtime

+

Often, it is useful to compile a program into an executable simulation, then +run the simulation with various inputs. This requires some means to pass data +and arguments to the compiled program each time it is executed. For example, +if the design models a micro-controller, one would like to run the compiled +simulation against a variety of different ROM images.

+

There are a variety of ways for a Verilog program to get data from the outside +world into the program at run time. Arguments can be entered on the command +line, and larger amounts of data can be read from files. The simplest method +is to take arguments from the command line.

+

Consider this running example of a square root calculator

+
module sqrt32(clk, rdy, reset, x, .y(acc));
+  input  clk;
+  output rdy;
+  input  reset;
+
+  input [31:0] x;
+  output [15:0] acc;
+
+  // acc holds the accumulated result, and acc2 is
+  //  the accumulated square of the accumulated result.
+  reg [15:0] acc;
+  reg [31:0] acc2;
+
+  // Keep track of which bit I'm working on.
+  reg [4:0]  bitl;
+  wire [15:0] bit = 1 << bitl;
+  wire [31:0] bit2 = 1 << (bitl << 1);
+
+  // The output is ready when the bitl counter underflows.
+  wire rdy = bitl[4];
+
+  // guess holds the potential next values for acc,
+  // and guess2 holds the square of that guess.
+  wire [15:0] guess  = acc | bit;
+  wire [31:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1);
+
+  task clear;
+     begin
+        acc = 0;
+        acc2 = 0;
+        bitl = 15;
+     end
+  endtask
+
+  initial clear;
+
+  always @(reset or posedge clk)
+     if (reset)
+      clear;
+     else begin
+        if (guess2 <= x) begin
+           acc  <= guess;
+           acc2 <= guess2;
+        end
+        bitl <= bitl - 1;
+     end
+
+endmodule
+
+
+

One could write the test bench as a program that passes a representative set +of input values into the device and checks the output result. However, we can +also write a program that takes on the command line an integer value to be +used as input to the device. We can write and compile this program, then pass +different input values on the run time command line without recompiling the +simulation.

+

This example demonstrates the use of the “$value$plusargs” to access command +line arguments of a simulation

+
module main;
+
+  reg clk, reset;
+  reg [31:0] x;
+  wire [15:0] y;
+  wire        rdy;
+
+  sqrt32 dut (clk, rdy, reset, x, y);
+
+  always #10 clk = ~clk;
+
+  initial begin
+     clk = 0;
+     reset = 1;
+
+     if (! $value$plusargs("x=%d", x)) begin
+        $display("ERROR: please specify +x=<value> to start.");
+        $finish;
+     end
+
+     #35 reset = 0;
+
+     wait (rdy) $display("y=%d", y);
+     $finish;
+  end // initial begin
+
+endmodule // main
+
+
+

The “$value$plusargs” system function takes a string pattern that describes +the format of the command line argument, and a reference to a variable that +receives the value. The “sqrt_plusargs” program can be compiled and executed +like this:

+
% iverilog -osqrt_plusargs.vvp sqrt_plusargs.v sqrt.v
+% vvp sqrt_plusargs.vvp +x=81
+y=    9
+
+
+

Notice that the “x=%d” string of the “$value$plusargs” function describes the +format of the argument. The “%d” matches a decimal value, which in the sample +run is “81”. This gets assigned to “x” by the “$value$plusargs” function, +which returns TRUE, and the simulation continues from there.

+

If two arguments have to be passed to the testbench then the main module would +be modified as follows

+
module main;
+
+  reg clk, reset;
+  reg  [31:0] x;
+  reg  [31:0] z;
+  wire [15:0] y1,y2;
+  wire        rdy1,rdy2;
+
+  sqrt32 dut1 (clk, rdy1, reset, x, y1);
+  sqrt32 dut2 (clk, rdy2, reset, z, y2);
+
+  always #10 clk = ~clk;
+
+  initial begin
+     clk = 0;
+     reset = 1;
+
+     if (! $value$plusargs("x=%d", x)) begin
+        $display("ERROR: please specify +x=<value> to start.");
+        $finish;
+     end
+
+     if (! $value$plusargs("z=%d", z)) begin
+        $display("ERROR: please specify +z=<value> to start.");
+        $finish;
+     end
+
+
+     #35 reset = 0;
+
+     wait (rdy1) $display("y1=%d", y1);
+     wait (rdy2) $display("y2=%d", y2);
+     $finish;
+  end // initial begin
+
+endmodule // main
+
+
+

and the “sqrt_plusargs” program would be compiled and executed as follows:

+
% iverilog -osqrt_plusargs.vvp sqrt_plusargs.v sqrt.v
+% vvp sqrt_plusargs.vvp +x=81 +z=64
+y1=    9
+y2=    8
+
+
+

In general, the “vvp” command that executes the compiled simulation takes a +few predefined argument flags, then the file name of the simulation. All the +arguments after the simulation file name are extended arguments to “vvp” and +are passed to the executed design. Extended arguments that start with a “+” +character are accessible through the “$test$plusargs” and “$value$plusargs” +system functions. Extended arguments that do not start with a “+” character +are only accessible to system tasks and functions written in C using the VPI.

+

In the previous example, the program pulls the argument from the command line, +assigns it to the variable “x”, and runs the sqrt device under test with that +value. This program can take the integer square root of any single value. Of +course, if you wish to test with a large number of input values, executing the +program many times may become tedious.

+

Another technique would be to put a set of input values into a data file, and +write the test bench to read the file. We can then edit the file to add new +input values, then rerun the simulation without compiling it again. The +advantage of this technique is that we can accumulate a large set of test +input values, and run the lot as a batch.

+

This example

+
module main;
+
+  reg clk, reset;
+  reg [31:0] data[4:0];
+  reg [31:0] x;
+  wire [15:0] y;
+  wire        rdy;
+
+  sqrt32 dut (clk, rdy, reset, x, y);
+
+  always #10 clk = ~clk;
+
+  integer i;
+  initial begin
+     /* Load the data set from the hex file. */
+     $readmemh("sqrt.hex", data);
+     for (i = 0 ;  i <= 4 ;  i = i + 1) begin
+       clk = 0;
+       reset = 1;
+
+       x = data[i];
+
+       #35 reset = 0;
+
+       wait (rdy) $display("y=%d", y);
+     end
+     $finish;
+  end // initial begin
+
+endmodule // main
+
+
+

demonstrates the use of “$readmemh” to read data samples from a file into a +Verilog array. Start by putting into the file “sqrt.hex” the numbers:

+
51
+19
+1a
+18
+1
+
+
+

Then run the simulation with the command sequence:

+
% iverilog -osqrt_readmem.vvp sqrt_readmem.vl sqrt.vl
+% vvp sqrt_readmem.vvp
+y=    9
+y=    5
+y=    5
+y=    4
+y=    1
+
+
+

It is easy enough to change this program to work with larger data sets, or to +change the “data.hex” file to contain different data. This technique is also +common for simulating algorithms that take in larger data sets. One can extend +this idea slightly by using a “$value$plusargs” statement to select the file +to read.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/verilog_attributes.html b/usage/verilog_attributes.html new file mode 100644 index 0000000000..0b97b7f99d --- /dev/null +++ b/usage/verilog_attributes.html @@ -0,0 +1,163 @@ + + + + + + + + + Verilog Attributes — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Verilog Attributes

+

This is a description of the various attributes that the Icarus Verilog tools +understand. The attributes are attached to objects using the “(* … *)” +syntax, which is described by the Verilog LRM.

+

Attributes that start with “ivl_” are Icarus Verilog specific are are probably +ignored by other tools.

+
+

Optimizations

+
    +
  • ivl_do_not_elide (snapshot 20140619 or later)

    +

    This applies to signals (i.e. reg, wire, etc.) and tells the optimizer to +not elide the signal, even if it is not referenced anywhere in the +design. This is useful if the signal is for some reason only accessed by +VPI/PLI code.

    +
  • +
+
+
+

Synthesis

+
    +
  • ivl_synthesis_cell

    +

    Applied to a module definition, this tells the synthesizer that the module +is a cell. The synthesizer does not descend into synthesis cells, as they +are assumed to be primitives in the target technology.

    +
  • +
  • ivl_synthesis_off

    +

    Attached to an “always” statement, this tells the synthesizer that the +statement is not to be synthesized. This may be useful, for example, to tell +the compiler that a stretch of code is test-bench code.

    +
  • +
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/vhdlpp_flags.html b/usage/vhdlpp_flags.html new file mode 100644 index 0000000000..f48c73d11e --- /dev/null +++ b/usage/vhdlpp_flags.html @@ -0,0 +1,183 @@ + + + + + + + + + vhdlpp Command Line Flags — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

vhdlpp Command Line Flags

+
    +
  • -D <token>

    +

    Debug flags. The token can be:

    +
      +
    • yydebug | no-yydebug

    • +
    • entities=<path>

    • +
    +
  • +
  • -L <path>

    +

    Library path. Add the directory name to the front of the library +search path. The library search path is initially empty.

    +
  • +
  • -V

    +

    Display version on stdout

    +
  • +
  • -v

    +

    Verbose: Display version on stderr, and enable verbose messages to +stderr.

    +
  • +
  • -w <path>

    +

    Work path. This is the directory where the working directory is.

    +
  • +
+
+

Library Format

+

The vhdlpp program stores libraries as directory that contain +packages. The name of the directory (in lower case) is the name of the +library as used on the “import” statement. Within that library, there +are packages in files named <foo>.pkg. For example:

+
<directory>/...
+   sample/...
+     test1.pkg
+     test2.pkg
+   bar/...
+     test3.pkg
+
+
+

Use the “+vhdl-libdir+<directory>” record in a config file to tell +Icarus Verilog that <directory> is a place to look for libraries. Then +in your VHDL code, access packages like this:

+
library sample;
+library bar;
+use sample.test1.all;
+use bar.test3.all;
+
+
+

The *.pkg files are just VHDL code containing only the package with +the same name. When Icarus Verilog encounters the “use <lib>.<name>.*;” +statement, it looks for the <name>.pkg file in the <lib> library and +parses that file to get the package header declared therein.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/vpi.html b/usage/vpi.html new file mode 100644 index 0000000000..4d5323505a --- /dev/null +++ b/usage/vpi.html @@ -0,0 +1,357 @@ + + + + + + + + + Using VPI — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

Using VPI

+

Icarus Verilog implements a portion of the PLI 2.0 API to Verilog. This allows +programmers to write C code that interfaces with Verilog simulations to +perform tasks otherwise impractical with straight Verilog. Many Verilog +designers, especially those who only use Verilog as a synthesis tool, can +safely ignore the entire matter of the PLI (and this chapter) but the designer +who wishes to interface a simulation with the outside world cannot escape VPI.

+

The rest of this article assumes some knowledge of C programming, Verilog PLI, +and of the compiler on your system. In most cases, Icarus Verilog assumes the +GNU Compilation System is the compiler you are using, so tips and instructions +that follow reflect that. If you are not a C programmer, or are not planning +any VPI modules, you can skip this entire article. There are references at the +bottom for information about more general topics.

+
+

How It Works

+

The VPI modules are compiled loadable object code that the runtime loads at +the user’s request. The user commands vvp to locate and load modules with the +“-m” switch. For example, to load the “sample.vpi” module:

+
% vvp -msample foo.vvp
+
+
+

The vvp run-time loads the modules first, before executing any of the +simulation, or even before compiling the vvp code. Part of the loading +includes invoking initialization routines. These routines register with the +run-time all the system tasks and functions that the module implements. Once +this is done, the run time loader can match names of the called system tasks +of the design with the implementations in the VPI modules.

+

(There is a special module, the system.vpi module, that is always loaded to +provide the core system tasks.)

+

The simulator run time (The “vvp” program) gets a handle on a freshly loaded +module by looking for the symbol “vlog_startup_routines” in the loaded +module. This table, provided by the module author and compiled into the +module, is a null terminated table of function pointers. The simulator calls +each of the functions in the table in order. The following simple C definition +defines a sample table:

+
void (*vlog_startup_routines[])() = {
+   hello_register,
+   0
+};
+
+
+

Note that the “vlog_startup_routines” table is an array of function pointers, +with the last pointer a 0 to mark the end. The programmer can organize the +module to include many startup functions in this table, if desired.

+

The job of the startup functions that are collected in the startup table is to +declare the system tasks and functions that the module provides. A module may +implement as many tasks/functions as desired, so a module can legitimately be +called a library of system tasks and functions.

+
+
+

Compiling VPI Modules

+

To compile and link a VPI module for use with Icarus Verilog, you must compile +all the source files of a module as if you were compiling for a DLL or shared +object. With gcc under Linux, this means compiling with the “-fpic” flag. The +module is then linked together with the vpi library like so:

+
% gcc -c -fpic hello.c
+% gcc -shared -o hello.vpi hello.o -lvpi
+
+
+

This assumes that the “vpi_user.h header file and the libvpi.a library file +are installed on your system so that gcc may find them. This is normally the +case under Linux and UNIX systems. An easier, the preferred method that works +on all supported systems is to use the single command:

+
% iverilog-vpi hello.c
+
+
+

The “iverilog-vpi” command takes as command arguments the source files for +your VPI module, compiles them with proper compiler flags, and links them into +a vpi module with any system specific libraries and linker flags that are +required. This simple command makes the “hello.vpi” module with minimum fuss.

+
+
+

A Worked Example

+

Let us try a complete, working example. Place the C code that follows into the +file hello.c:

+
# include  <vpi_user.h>
+
+static int hello_compiletf(char*user_data)
+{
+      return 0;
+}
+
+static int hello_calltf(char*user_data)
+{
+      vpi_printf("Hello, World!\n");
+      return 0;
+}
+
+void hello_register()
+{
+      s_vpi_systf_data tf_data;
+
+      tf_data.type      = vpiSysTask;
+      tf_data.tfname    = "$hello";
+      tf_data.calltf    = hello_calltf;
+      tf_data.compiletf = hello_compiletf;
+      tf_data.sizetf    = 0;
+      tf_data.user_data = 0;
+      vpi_register_systf(&tf_data);
+}
+
+void (*vlog_startup_routines[])() = {
+    hello_register,
+    0
+};
+
+
+

and place the Verilog code that follows into hello.v:

+
module main;
+  initial $hello;
+endmodule
+
+
+

Next, compile and execute the code with these steps:

+
% iverilog-vpi hello.c
+% iverilog -ohello.vvp hello.v
+% vvp -M. -mhello hello.vvp
+Hello, World!
+
+
+

The compile and link in this example are conveniently combined into the +“iverilog-vpi” command. The “iverilog” command then compiles the “hello.v” +Verilog source file to the “hello.vvp” program. Next, the “vvp” command +demonstrates the use of the “-M” and “-m” flags to specify a vpi module search +directory and vpi module name. Specifically, they tell the “vvp” command where +to find the module we just compiled.

+

The “vvp” command, when executed as above, loads the “hello.vpi” module that +it finds in the current working directory. When the module is loaded, the +vlog_startup_routines table is scanned, and the “hello_register” function is +executed. The “hello_register” function in turn tells “vvp” about the system +tasks that are included in this module.

+

After the modules are all loaded, the “hello.vvp” design file is loaded and +its call to the “$hello” system task is matched up to the version declared by +the module. While “vvp” compiles the “hello.vvp” source, any calls to “$hello” +are referred to the “compiletf” function. This function is called at compile +time and can be used to check parameters to system tasks or function. It can +be left empty like this, or left out completely. The “compiletf” function can +help performance by collecting parameter checks in compile time, so they do +not need to be done each time the system task is run, thus potentially saving +execution time overall.

+

When the run-time executes the call to the hello system task, the +“hello_calltf” function is invoked in the loaded module, and thus the output +is generated. The “calltf” function is called at run time when the Verilog +code actually executes the system task. This is where the active code of the +task belongs.

+
+
+

System Function Return Types

+

Icarus Verilog supports system functions as well as system tasks, but there is +a complication. Notice how the module that you compile is only loaded by the +“vvp” program. This is mostly not an issue, but elaboration of expressions +needs to keep track of types, so the main compiler needs to know the return +type of functions.

+

Starting with Icarus Verilog v11, the solution is quite simple. The names and +locations of the user’s VPI modules can be passed to the compiler via the +“iverilog” -m and -L flags and the IVERILOG_VPI_MODULE_PATH environment +variable. The compiler will load and analyse the specified modules to +automatically determine any function return types. The compiler will also +automatically pass the names and locations of the specified modules to the +“vvp” program, so that they don’t need to be specified again on the “vvp” +command line.

+

For Icarus Verilog versions prior to v11, the solution requires that the +developer of a module include the table in a form that the compiler can +read. The System Function Table file carries this information. A simple +example looks like this:

+
# Example sft declarations of some common functions
+$random      vpiSysFuncInt
+$bitstoreal  vpiSysFuncReal
+$realtobits  vpiSysFuncSized 64 unsigned
+
+
+

This demonstrates the format of the file and support types. Each line contains +a comment (starts with “#”) or a type declaration for a single function. The +declaration starts with the name of the system function (including the leading +“$”) and ends with the type. The supported types are:

+
    +
  • vpiSysFuncInt

  • +
  • vpiSysFuncReal

  • +
  • vpiSysFuncSized <wid> <signed|unsigned>

  • +
+

Any functions that do not have an explicit type declaration in an SFT file are +implicitly taken to be “vpiSysFuncSized 32 unsigned”.

+

The module author provides, along with the “.vpi” file that is the module, a +“.sft” that declares all the function return types. For example, if the file +is named “example.sft”, pass it to the “iverilog” command line or in the +command file exactly as if it were an ordinary source file.

+
+
+

Cadence PLI Modules

+

With the cadpli module, Icarus Verilog is able to load PLI1 applications that +were compiled and linked to be dynamic loaded by Verilog-XL or +NC-Verilog. This allows Icarus Verilog users to run third-party modules that +were compiled to interface with XL or NC. Obviously, this only works on the +operating system that the PLI application was compiled to run on. For example, +a Linux module can only be loaded and run under Linux. In addition, a 64-bit +version of vvp can only load 64-bit PLI1 applications, etc.

+

Icarus Verilog uses an interface module, the “cadpli” module, to connect the +worlds. This module is installed with Icarus Verilog, and is invoked by the +usual -m flag to iverilog or vvp. This module in turn scans the extended +arguments, looking for -cadpli= arguments. The latter specify the share object +and bootstrap function for running the module. For example, to run the module +product.so, that has the bootstrap function “my_boot”:

+
% vvp -mcadpli a.out -cadpli=./product.so:my_boot
+
+
+

The “-mcadpli” argument causes vvp to load the cadpli.vpl library module. This +activates the -cadpli= argument interpreter. The -cadpli=<module>:<boot_func> +argument, then, causes vvp, through the cadpli module, to load the loadable +PLI application, invoke the my_boot function to get a veriusertfs table, and +scan that table to register the system tasks and functions exported by that +object. The format of the -cadpli= extended argument is essentially the same +as the +loadpli1= argument to Verilog-XL.

+

The integration from this point is seamless. The PLI application hardly knows +that it is being invoked by Icarus Verilog instead of Verilog-XL, so operates +as it would otherwise.

+
+
+

Other References

+

Since the above only explains how to get PLI/VPI working with Icarus Verilog, +here are some references to material to help with the common aspects of +PLI/VPI.

+
    +
  • Principles of Verilog PLI by Swapnajit Mittra. ISBN 0-7923-8477-6

  • +
  • The Verilog PLI Handbook by Stuart Sutherland. ISBN 0-7923-8489-X

  • +
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/vvp_debug.html b/usage/vvp_debug.html new file mode 100644 index 0000000000..09bf7d82df --- /dev/null +++ b/usage/vvp_debug.html @@ -0,0 +1,270 @@ + + + + + + + + + VVP Interactive Mode — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

VVP Interactive Mode

+

The vvp command has an interactive debug mode, where you can stop the +simulation and browse the current state of the simulation. There are +a couple ways to enter the debug mode, but once in interactive debug +mode, the usage is the same. Consider the example below:

+
module clock(output reg clock);
+  initial clock = 1'b1;
+  always #100 clock = !clock;
+endmodule // clock
+
+module main;
+
+  reg [2:0] foo;
+  wire             clk;
+
+  clock foo_clock(clk);
+
+  always @(posedge clk)
+    foo <= foo + 1;
+
+  initial begin
+     foo = 3'b000;
+    #250 $stop;
+  end
+
+endmodule
+
+
+

In examples that follow, we will use the above sample program.

+
+

Enter Interactive Mode

+

The first and most common method is to put “$stop” system task +calls in the simulation at the times where you want to simulation +to break and enter interactive mode. The example above has a $stop, +so the output looks like this:

+
../foo.vl:25: $stop called at 250 (1s)
+** VVP Stop(0) **
+** Flushing output streams.
+** Current simulation time is 250 ticks.
+>
+
+
+

You can get some interactive help by using the “help” command:

+
> help
+Commands can be from the following table of base commands,
+or can be invocations of system tasks/functions.
+
+cd       - Synonym for push.
+cont     - Resume (continue) the simulation
+finish   - Finish the simulation.
+help     - Get help.
+list     - List items in the current scope.
+load     - Load a VPI module, a la vvp -m.
+ls       - Shorthand for "list".
+pop      - Pop one scope from the scope stack.
+push     - Descend into the named scope.
+step     - Single-step the scheduler for 1 event.
+time     - Print the current simulation time.
+trace    - Control statement tracing (on/off) when the code is instrumented.
+where    - Show current scope, and scope hierarchy stack.
+
+If the command name starts with a '$' character, it
+is taken to be the name of a system task, and a call is
+built up and executed. For example, "$display foo" will
+call the function as $display(foo).
+
+
+

You can also enter interactive mode at the terminal by interrupting the +execution with a “^C” (Control-C) character. The vvp engine catches the +terminal interrupt and drops you into the interactive prompt:

+
^C** VVP Stop(0) **
+** Flushing output streams.
+** Current simulation time is 533928600 ticks.
+>
+
+
+

This could be useful if you suspect that your simulation is stuck in +an infinite loop and you want to rummage around and see what’s going on.

+

And finally, you can pass the “-s” command line flag to vvp to tell it +to execute “$stop” at the beginning of the simulation, before any other +events are executed. This may be useful as a way to manually set up some +details about the simulation.

+
+
+

Browsing the Design

+

Now that you are in the interactive prompt, you can browse +around the design:

+
> ls
+2 items in this scope:
+package : $unit
+module  : main
+> cd main
+> ls
+3 items in this scope:
+reg     : foo[2:0]
+module  : foo_clock
+net     : clk
+> where
+module main
+> $display foo
+1
+> cd foo_clock
+> where
+module foo_clock
+module main
+> ls
+2 items in this scope:
+port    : clock -- output
+reg     : clock
+
+
+

In the above example, the ‘cd’ and ‘pop’ commands descend into a scope +or pop back up a scope level. The ‘where’ command shows the scope stack, +and the ‘ls’ command lists the items present in the scope. With these +commands, one can browse freely throughout the design scope hierarchy.

+

It is also possible to call system tasks within the debug mode. The call +to the “$display” function is an example of this. In general, any system +task can be invoked, in the current context, with the objects that are +included on the command line passed as arguments. The arguments can be +variables or nets, and various kinds of literals:

+
> ls
+2 items in this scope:
+port    : clock -- output
+reg     : clock
+> $display "Hello, World! " 10 " " clock
+Hello, World!          10 1
+
+
+

This is a great way to call custom system tasks as well. And system task +that vvp knows about can be invoked this way.

+
+
+

Leave Interactive Mode

+

After you are done probing around in the interactive mode, you can +resume the simulation, or termimate execution. Resume the simulation +with the “cont” command, and terminate the simulation with the +“finish” command. The latter is the same as executing the +“$finish” system task.

+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/vvp_flags.html b/usage/vvp_flags.html new file mode 100644 index 0000000000..c93b922fa4 --- /dev/null +++ b/usage/vvp_flags.html @@ -0,0 +1,233 @@ + + + + + + + + + VVP Command Line Flags — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

VVP Command Line Flags

+

The vvp command is the simulation run-time engine. The command line for vvp +execution is first the options and flags, then the vvp input file, and finally +extended arguments. Typical usage looks like this:

+
% vvp <flags> foo.vvp <extended arguments>
+
+
+
+

Options/Flags

+

These options/flags go before the path to the vvp-executable program. They +effect behavior of the vvp runtime engine, including preparation for +simulation.

+
    +
  • -l<logfile>

    +

    This flag specifies a logfile where all MCI <stdlog> output goes. Specify +logfile as ‘-’ to send log output to <stderr>. $display and friends send +their output both to <stdout> and <stdlog>.

    +
  • +
  • -M<path>

    +

    Add the directory path to the (VPI) module search path. Multiple “-M” flags +are allowed, and the directories are added in the order that they are given +on the command line.

    +

    The string “-M-” is special, in that it doesn’t add a directory to the +path. It instead removes the compiled directory. This is generally used +only for development of the vvp engine.

    +
  • +
  • -m<module>

    +

    Name a VPI module that should be loaded. The vvp engine looks for the named +module in the module search path, which includes the compiled in default +directory and directories given by “-M” flags.

    +

    NOTE: Starting with v11.0, the VPI modules to be loaded can be specified +when you compile your design. This allows the compiler to automatically +determine the return types of user-defined system functions. If specified at +compile-time, there is no need to specify them again here.

    +
  • +
  • -s

    +

    $stop right away, in the beginning of the simulation. This kicks the +vvp program into interactive debug mode.

    +
  • +
  • -v

    +

    Show verbose progress while setting up or cleaning up the runtime +engine. This also displays some performance information.

    +
  • +
+
+
+

Extended Arguments

+

The extended arguments are available to the simulation runtime, especially +system tasks, system functions and any VPI/PLI code. Extended arguments that +start with a “+” character are left for use by the user via the $plus$flag and +$plus$value functions.

+
+

VCD/FST/LXT Arguments

+

If not otherwise specified, the vvp engine will by default use VCD formats to +support the $dumpvars system task. The flags described here can alter that +behavior.

+
    +
  • -none/-vcd-none/-vcd-off/-fst-none

    +

    Disable trace output. The trace output will be stubbed so that no trace file +is created and the cost of dumping is avoided. All off these options are +synonyms for turning of dumping.

    +
  • +
  • -fst

    +

    Generate FST format outputs instead of VCD format waveform dumps. This is +the preferred output format if using GTKWave for viewing waveforms.

    +
  • +
  • -lxt/-lxt2

    +

    Generate LXT or LXT2format instead of VCD format waveform dumps. The LXT2 +format is more advanced.

    +
  • +
  • -dumpfile=<name>

    +

    Set the default dumpfile. If unspecified, the default is “dump”. This +command line flag allows you do change it. If no suffix is specified, +then the suffix will be chosen based on the dump type. In any case, the +$dumpfile system task overrides this flag.

    +
  • +
+
+
+

SDF Support

+

The Icarus Verilog support for SDF back-annotation can take some extended +arguments to control aspects of SDF support.

+
    +
  • -sdf-warn

    +

    Print warnings during load of/annotation from an SDF file.

    +
  • +
  • -sdf-info

    +

    Print interesting information about an SDF file while parsing it.

    +
  • +
  • -sdf-verbose

    +

    Print warnings and info messages.

    +
  • +
+
+
+
+

Environment Variables

+

The vvp program pays attention to certain environment variables.

+
    +
  • IVERILOG_DUMPER

  • +
+
+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/usage/vvp_library.html b/usage/vvp_library.html new file mode 100644 index 0000000000..9470f31269 --- /dev/null +++ b/usage/vvp_library.html @@ -0,0 +1,155 @@ + + + + + + + + + VVP as a library — Icarus Verilog documentation + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +
+

VVP as a library

+

If configured with

+
--enable-libvvp
+
+
+

the vvp program will be built as a small stub that +depends on a shared library, libvvp.so. +The library may also be used to include a vvp simulation +in a larger program. Typically, the simulation communicates +with its host program using VPI, but since +almost all the functions of vvp are included in the library +it may be possible to use text output and interactive mode.

+

The accessible functions of the library are defined and documented +in the header file, vvp/libvvp.h. Although vvp is a C++ program, the +header file presents a C interface.

+

Note that the vvp software was not designed to be used this way +and the library is a straightforward recompilation of the program code. +That imposes some restrictions, mostly arising from the use +of static variables: only a single run of a single simulation instance +can be expected to work without special actions. +To mitigate these restrictions, the library may by loaded dynamically +and unloaded at the end of each simulation run. +Parallel simulation should be possible by making multiple copies +of the library with different names.

+
+ + +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file