[
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n\n# Custom for Visual Studio\n*.cs     diff=csharp\n*.sln    merge=union\n*.csproj merge=union\n*.vbproj merge=union\n*.fsproj merge=union\n*.dbproj merge=union\n\n# Standard to msysgit\n*.doc\t diff=astextplain\n*.DOC\t diff=astextplain\n*.docx diff=astextplain\n*.DOCX diff=astextplain\n*.dot  diff=astextplain\n*.DOT  diff=astextplain\n*.pdf  diff=astextplain\n*.PDF\t diff=astextplain\n*.rtf\t diff=astextplain\n*.RTF\t diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "#################\n## Eclipse\n#################\n\n*.pydevproject\n.project\n.metadata\nbin/\ntmp/\n*.tmp\n*.bak\n*.swp\n*~.nib\nlocal.properties\n.classpath\n.settings/\n.loadpath\n\n# External tool builders\n.externalToolBuilders/\n\n# Locally stored \"Eclipse launch configurations\"\n*.launch\n\n# CDT-specific\n.cproject\n\n# PDT-specific\n.buildpath\n\n\n#################\n## Visual Studio\n#################\n\n## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.sln.docstates\n\n# Build results\n\n[Dd]ebug/\n[Rr]elease/\nx64/\nbuild/\n[Bb]in/\n[Oo]bj/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n*_i.c\n*_p.c\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.log\n*.scc\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n*.cachefile\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n*.ncrunch*\n.*crunch*.local.xml\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.Publish.xml\n*.pubxml\n\n# NuGet Packages Directory\n## TODO: If you have NuGet Package Restore enabled, uncomment the next line\n#packages/\n\n# Windows Azure Build Output\ncsx\n*.build.csdef\n\n# Windows Store app package directory\nAppPackages/\n\n# Others\nsql/\n*.Cache\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.[Pp]ublish.xml\n*.pfx\n*.publishsettings\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file to a newer\n# Visual Studio version. Backup files are not needed, because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\nApp_Data/*.mdf\nApp_Data/*.ldf\n\n#############\n## Windows detritus\n#############\n\n# Windows image file caches\nThumbs.db\nehthumbs.db\n\n# Folder config file\nDesktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Mac crap\n.DS_Store\n\n\n#############\n## Python\n#############\n\n*.py[co]\n\n# Packages\n*.egg\n*.egg-info\ndist/\nbuild/\neggs/\nparts/\nvar/\nsdist/\ndevelop-eggs/\n.installed.cfg\n\n# Installer logs\npip-log.txt\n\n# Unit test / coverage reports\n.coverage\n.tox\n\n#Translations\n*.mo\n\n#Mr Developer\n.mr.developer.cfg\n"
  },
  {
    "path": "BeMicro/README.txt",
    "content": "BeMicro port by litecoin forum member \"Minor\" https://forum.litecoin.net/index.php?action=profile;u=15431\n\n+-------------------------------------------------------------------------------+\n; Flow Summary                                                                  ;\n+------------------------------------+------------------------------------------+\n; Flow Status                        ; Successful - Wed Sep 18 13:46:51 2013    ;\n; Quartus II Version                 ; 10.1 Build 153 11/29/2010 SJ Web Edition ;\n; Revision Name                      ; ltcminer                                 ;\n; Top-level Entity Name              ; ltcminer                                 ;\n; Family                             ; Cyclone IV E                             ;\n; Device                             ; EP4CE22F17C7                             ;\n; Timing Models                      ; Final                                    ;\n; Total logic elements               ; 18,713 / 22,320 ( 84 % )                 ;\n;     Total combinational functions  ; 16,012 / 22,320 ( 72 % )                 ;\n;     Dedicated logic registers      ; 10,483 / 22,320 ( 47 % )                 ;\n; Total registers                    ; 10483                                    ;\n; Total pins                         ; 9 / 154 ( 6 % )                          ;\n; Total virtual pins                 ; 0                                        ;\n; Total memory bits                  ; 524,288 / 608,256 ( 86 % )               ;\n; Embedded Multiplier 9-bit elements ; 0 / 132 ( 0 % )                          ;\n; Total PLLs                         ; 1 / 4 ( 25 % )                           ;\n+------------------------------------+------------------------------------------+\n"
  },
  {
    "path": "BeMicro/ltcminer.qpf",
    "content": "# -------------------------------------------------------------------------- #\n#\n# Copyright (C) 1991-2010 Altera Corporation\n# Your use of Altera Corporation's design tools, logic functions \n# and other software and tools, and its AMPP partner logic \n# functions, and any output files from any of the foregoing \n# (including device programming or simulation files), and any \n# associated documentation or information are expressly subject \n# to the terms and conditions of the Altera Program License \n# Subscription Agreement, Altera MegaCore Function License \n# Agreement, or other applicable license agreement, including, \n# without limitation, that your use is for the sole purpose of \n# programming logic devices manufactured by Altera and sold by \n# Altera or its authorized distributors.  Please refer to the \n# applicable agreement for further details.\n#\n# -------------------------------------------------------------------------- #\n#\n# Quartus II\n# Version 10.0 Build 262 08/18/2010 Service Pack 1 SJ Web Edition\n# Date created = 19:43:05  May 18, 2011\n#\n# -------------------------------------------------------------------------- #\n\nQUARTUS_VERSION = \"10.0\"\nDATE = \"19:43:05  May 18, 2011\"\n\n# Revisions\n\nPROJECT_REVISION = \"ltcminer\"\n\n"
  },
  {
    "path": "BeMicro/ltcminer.qsf",
    "content": "# -------------------------------------------------------------------------- #\n#\n# Copyright (C) 1991-2010 Altera Corporation\n# Your use of Altera Corporation's design tools, logic functions\n# and other software and tools, and its AMPP partner logic\n# functions, and any output files from any of the foregoing\n# (including device programming or simulation files), and any\n# associated documentation or information are expressly subject\n# to the terms and conditions of the Altera Program License\n# Subscription Agreement, Altera MegaCore Function License\n# Agreement, or other applicable license agreement, including,\n# without limitation, that your use is for the sole purpose of\n# programming logic devices manufactured by Altera and sold by\n# Altera or its authorized distributors.  Please refer to the\n# applicable agreement for further details.\n#\n# -------------------------------------------------------------------------- #\n#\n# Quartus II\n# Version 10.0 Build 262 08/18/2010 Service Pack 1 SJ Web Edition\n# Date created = 05:05:52  March 02, 2011\n#\n# -------------------------------------------------------------------------- #\n#\n# Notes:\n#\n# 1) The default values for assignments are stored in the file:\n#    If this file doesn't exist, see file:\n#\t\tassignment_defaults.qdf\n#\n# 2) Altera recommends that you do not modify this file. This\n#    file is updated automatically by the Quartus II software\n#    and any changes you make may be lost or overwritten.\n#\n# -------------------------------------------------------------------------- #\n\n\nset_global_assignment -name FAMILY \"Cyclone IV E\"\nset_global_assignment -name DEVICE EP4CE22F17C7\nset_global_assignment -name TOP_LEVEL_ENTITY ltcminer\nset_global_assignment -name LAST_QUARTUS_VERSION 10.1\nset_global_assignment -name MIN_CORE_JUNCTION_TEMP 0\nset_global_assignment -name MAX_CORE_JUNCTION_TEMP 85\nset_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1\nset_global_assignment -name STRATIX_DEVICE_IO_STANDARD \"2.5 V\"\nset_global_assignment -name PROJECT_OUTPUT_DIRECTORY quartus_output\nset_global_assignment -name EDA_SIMULATION_TOOL \"<None>\"\nset_global_assignment -name EDA_MAP_ILLEGAL_CHARACTERS OFF -section_id eda_simulation\nset_global_assignment -name EDA_TIME_SCALE \"1 ps\" -section_id eda_simulation\nset_global_assignment -name EDA_OUTPUT_DATA_FORMAT NONE -section_id eda_simulation\nset_global_assignment -name EDA_ENABLE_GLITCH_FILTERING OFF -section_id eda_simulation\nset_global_assignment -name EDA_WRITE_NODES_FOR_POWER_ESTIMATION OFF -section_id eda_simulation\nset_global_assignment -name EDA_TEST_BENCH_DESIGN_INSTANCE_NAME moogerfoogin -section_id eda_simulation\nset_global_assignment -name POWER_USE_PVA OFF\nset_global_assignment -name POWER_DEFAULT_TOGGLE_RATE 65%\nset_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF\nset_global_assignment -name POWER_PRESET_COOLING_SOLUTION \"NO HEAT SINK WITH STILL AIR\"\nset_global_assignment -name POWER_BOARD_THERMAL_MODEL \"NONE (CONSERVATIVE)\"\nset_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON\nset_global_assignment -name ALLOW_ANY_RAM_SIZE_FOR_RECOGNITION ON\nset_global_assignment -name ALLOW_ANY_ROM_SIZE_FOR_RECOGNITION ON\nset_global_assignment -name ALLOW_ANY_SHIFT_REGISTER_SIZE_FOR_RECOGNITION ON\nset_global_assignment -name ADD_PASS_THROUGH_LOGIC_TO_INFERRED_RAMS ON\nset_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON\nset_global_assignment -name REMOVE_DUPLICATE_REGISTERS ON\nset_location_assignment PIN_E1 -to osc_clk\nset_instance_assignment -name IO_STANDARD \"3.3-V LVTTL\" -to osc_clk\nset_location_assignment PIN_N15 -to LEDS_out[0]\nset_location_assignment PIN_K5  -to LEDS_out[1]\nset_location_assignment PIN_P9  -to LEDS_out[2]\nset_location_assignment PIN_P15 -to LEDS_out[3]\nset_location_assignment PIN_R10 -to LEDS_out[4]\nset_location_assignment PIN_L13 -to LEDS_out[5]\nset_location_assignment PIN_D1  -to LEDS_out[6]\nset_location_assignment PIN_B1  -to LEDS_out[7]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[7]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[6]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[5]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[4]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[3]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[2]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[1]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[0]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[7]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[6]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[5]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[3]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[4]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[2]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[1]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[0]\nset_global_assignment -name VERILOG_MACRO \"HALFRAM=1\"\n#set_global_assignment -name QIP_FILE halfram.qip\n\nset_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top\nset_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top\nset_global_assignment -name PARTITION_COLOR 16764057 -section_id Top\nset_global_assignment -name SMART_RECOMPILE ON\nset_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED\nset_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON\nset_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON\nset_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON\nset_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION ON\nset_global_assignment -name ROUTER_TIMING_OPTIMIZATION_LEVEL MAXIMUM\nset_global_assignment -name AUTO_PACKED_REGISTERS_STRATIXII NORMAL\nset_global_assignment -name FITTER_EFFORT \"STANDARD FIT\"\nset_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON\nset_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON\nset_global_assignment -name VERILOG_FILE ../source/ltcminer.v\nset_global_assignment -name VERILOG_FILE ../source/hashcore.v\nset_global_assignment -name VERILOG_FILE ../source/altera_ram.v\nset_global_assignment -name VERILOG_FILE ../source/salsa.v\nset_global_assignment -name VERILOG_FILE ../source/sha256_transform.v\nset_global_assignment -name VERILOG_FILE \"../source/sha-256-functions.v\"\nset_global_assignment -name VERILOG_FILE ../source/altera_pll.v\nset_global_assignment -name VERILOG_FILE ../source/altera_virtual_wire.v\nset_global_assignment -name SDC_FILE ltcminer.sdc\nset_global_assignment -name VERILOG_MACRO \"SPEED_MHZ=25\"\nset_global_assignment -name VERILOG_MACRO \"INVERTLEDS=1\"\nset_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top"
  },
  {
    "path": "BeMicro/ltcminer.sdc",
    "content": "##\n#\n# Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n#\n#\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n# \n##\n\ncreate_clock -period 20.000 -name osc_clk osc_clk\n\nderive_pll_clocks\nderive_clock_uncertainty\n\n"
  },
  {
    "path": "DE0-Nano/ltcminer.qpf",
    "content": "# -------------------------------------------------------------------------- #\n#\n# Copyright (C) 1991-2010 Altera Corporation\n# Your use of Altera Corporation's design tools, logic functions \n# and other software and tools, and its AMPP partner logic \n# functions, and any output files from any of the foregoing \n# (including device programming or simulation files), and any \n# associated documentation or information are expressly subject \n# to the terms and conditions of the Altera Program License \n# Subscription Agreement, Altera MegaCore Function License \n# Agreement, or other applicable license agreement, including, \n# without limitation, that your use is for the sole purpose of \n# programming logic devices manufactured by Altera and sold by \n# Altera or its authorized distributors.  Please refer to the \n# applicable agreement for further details.\n#\n# -------------------------------------------------------------------------- #\n#\n# Quartus II\n# Version 10.0 Build 262 08/18/2010 Service Pack 1 SJ Web Edition\n# Date created = 19:43:05  May 18, 2011\n#\n# -------------------------------------------------------------------------- #\n\nQUARTUS_VERSION = \"10.0\"\nDATE = \"19:43:05  May 18, 2011\"\n\n# Revisions\n\nPROJECT_REVISION = \"ltcminer\"\n\n"
  },
  {
    "path": "DE0-Nano/ltcminer.qsf",
    "content": "# -------------------------------------------------------------------------- #\n#\n# Copyright (C) 1991-2010 Altera Corporation\n# Your use of Altera Corporation's design tools, logic functions\n# and other software and tools, and its AMPP partner logic\n# functions, and any output files from any of the foregoing\n# (including device programming or simulation files), and any\n# associated documentation or information are expressly subject\n# to the terms and conditions of the Altera Program License\n# Subscription Agreement, Altera MegaCore Function License\n# Agreement, or other applicable license agreement, including,\n# without limitation, that your use is for the sole purpose of\n# programming logic devices manufactured by Altera and sold by\n# Altera or its authorized distributors.  Please refer to the\n# applicable agreement for further details.\n#\n# -------------------------------------------------------------------------- #\n#\n# Quartus II\n# Version 10.0 Build 262 08/18/2010 Service Pack 1 SJ Web Edition\n# Date created = 05:05:52  March 02, 2011\n#\n# -------------------------------------------------------------------------- #\n#\n# Notes:\n#\n# 1) The default values for assignments are stored in the file:\n#    If this file doesn't exist, see file:\n#\t\tassignment_defaults.qdf\n#\n# 2) Altera recommends that you do not modify this file. This\n#    file is updated automatically by the Quartus II software\n#    and any changes you make may be lost or overwritten.\n#\n# -------------------------------------------------------------------------- #\n\n\nset_global_assignment -name FAMILY \"Cyclone IV E\"\nset_global_assignment -name DEVICE EP4CE22F17C6\nset_global_assignment -name TOP_LEVEL_ENTITY ltcminer\nset_global_assignment -name ORIGINAL_QUARTUS_VERSION \"10.0 SP1\"\nset_global_assignment -name PROJECT_CREATION_TIME_DATE \"17:52:09  MAY 05, 2011\"\nset_global_assignment -name LAST_QUARTUS_VERSION 10.1\nset_global_assignment -name MIN_CORE_JUNCTION_TEMP 0\nset_global_assignment -name MAX_CORE_JUNCTION_TEMP 85\nset_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1\nset_global_assignment -name STRATIX_DEVICE_IO_STANDARD \"2.5 V\"\nset_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top\nset_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top\nset_global_assignment -name PARTITION_COLOR 16764057 -section_id Top\nset_global_assignment -name LL_ROOT_REGION ON -section_id \"Root Region\"\nset_global_assignment -name LL_MEMBER_STATE LOCKED -section_id \"Root Region\"\nset_global_assignment -name PROJECT_OUTPUT_DIRECTORY quartus_output\nset_global_assignment -name EDA_SIMULATION_TOOL \"<None>\"\nset_global_assignment -name EDA_MAP_ILLEGAL_CHARACTERS OFF -section_id eda_simulation\nset_global_assignment -name EDA_TIME_SCALE \"1 ps\" -section_id eda_simulation\nset_global_assignment -name EDA_OUTPUT_DATA_FORMAT NONE -section_id eda_simulation\nset_global_assignment -name EDA_ENABLE_GLITCH_FILTERING OFF -section_id eda_simulation\nset_global_assignment -name EDA_WRITE_NODES_FOR_POWER_ESTIMATION OFF -section_id eda_simulation\nset_global_assignment -name EDA_TEST_BENCH_DESIGN_INSTANCE_NAME moogerfoogin -section_id eda_simulation\nset_global_assignment -name POWER_USE_PVA OFF\nset_global_assignment -name POWER_DEFAULT_TOGGLE_RATE 65%\nset_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF\nset_global_assignment -name POWER_PRESET_COOLING_SOLUTION \"NO HEAT SINK WITH STILL AIR\"\nset_global_assignment -name POWER_BOARD_THERMAL_MODEL \"NONE (CONSERVATIVE)\"\nset_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON\nset_global_assignment -name ALLOW_ANY_RAM_SIZE_FOR_RECOGNITION ON\nset_global_assignment -name ALLOW_ANY_ROM_SIZE_FOR_RECOGNITION ON\nset_global_assignment -name ALLOW_ANY_SHIFT_REGISTER_SIZE_FOR_RECOGNITION ON\nset_global_assignment -name ADD_PASS_THROUGH_LOGIC_TO_INFERRED_RAMS ON\nset_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON\nset_global_assignment -name REMOVE_DUPLICATE_REGISTERS ON\nset_location_assignment PIN_R8 -to osc_clk\nset_location_assignment PIN_A15 -to LEDS_out[0]\nset_location_assignment PIN_A11 -to LEDS_out[3]\nset_location_assignment PIN_A13 -to LEDS_out[1]\nset_location_assignment PIN_B13 -to LEDS_out[2]\nset_location_assignment PIN_D1 -to LEDS_out[4]\nset_location_assignment PIN_F3 -to LEDS_out[5]\nset_location_assignment PIN_B1 -to LEDS_out[6]\nset_location_assignment PIN_L3 -to LEDS_out[7]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[7]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[6]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[5]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[4]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[3]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[2]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[1]\nset_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to LEDS_out[0]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[7]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[6]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[5]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[3]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[4]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[2]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[0]\nset_instance_assignment -name SLEW_RATE 0 -to LEDS_out[1]\nset_global_assignment -name VERILOG_FILE \"../source/ltcminer.v\"\nset_global_assignment -name VERILOG_FILE \"../source/hashcore.v\"\nset_global_assignment -name VERILOG_FILE \"../source/altera_ram.v\"\nset_global_assignment -name VERILOG_FILE \"../source/salsa.v\"\nset_global_assignment -name VERILOG_FILE \"../source/sha256_transform.v\"\nset_global_assignment -name VERILOG_FILE \"../source/sha-256-functions.v\"\nset_global_assignment -name VERILOG_FILE \"../source/altera_pll.v\"\nset_global_assignment -name VERILOG_FILE \"../source/altera_virtual_wire.v\"\nset_global_assignment -name VERILOG_MACRO \"HALFRAM=1\"\n#set_global_assignment -name QIP_FILE halfram.qip\nset_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top"
  },
  {
    "path": "DE0-Nano/ltcminer.sdc",
    "content": "##\n#\n# Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n#\n#\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n# \n##\n\ncreate_clock -period 20.000 -name osc_clk osc_clk\n\nderive_pll_clocks\nderive_clock_uncertainty\n\n"
  },
  {
    "path": "DE2-115-Single/README.txt",
    "content": "Single core version for DE2-115 using full sized scratchpad (UNTESTED)\n\nFor multipe cores simply replicate hashcore with different nonce_msb values and implement\na golden_nonce queue for results (a simple multiplexer latching on golden_nonce_match\nwill suffice). An dual core example is provided as a comment in ltcminer.v\nIts a little inefficient as the sha256 engine is replicated, but this will be rather\ncomplicated to fix.\n\nIt probably best to use half-sized scratchpads for the multicore version as\nthis doubles the number of cores that can be fitted for a 60% improvement in\nthroughput (the half cores being 80% as fast as a full scratchpad)\n    set_global_assignment -name VERILOG_MACRO \"HALFRAM=1\"\n\nThis note from the previous version of the README is obsolete as multicore is now\nenabled by default ...\n   For multicore, set the following in ltcminer.qsf ...\n       set_global_assignment -name VERILOG_MACRO \"MULTICORE=1\"\n   (Or use the assignments/settings menu in quartus to set it)\nUse the NOMULTICORE macro to revert to previous behaviour.\n\n"
  },
  {
    "path": "DE2-115-Single/ltcminer.qpf",
    "content": "# -------------------------------------------------------------------------- #\n#\n# Copyright (C) 1991-2010 Altera Corporation\n# Your use of Altera Corporation's design tools, logic functions \n# and other software and tools, and its AMPP partner logic \n# functions, and any output files from any of the foregoing \n# (including device programming or simulation files), and any \n# associated documentation or information are expressly subject \n# to the terms and conditions of the Altera Program License \n# Subscription Agreement, Altera MegaCore Function License \n# Agreement, or other applicable license agreement, including, \n# without limitation, that your use is for the sole purpose of \n# programming logic devices manufactured by Altera and sold by \n# Altera or its authorized distributors.  Please refer to the \n# applicable agreement for further details.\n#\n# -------------------------------------------------------------------------- #\n#\n# Quartus II\n# Version 10.1 Build 153 11/29/2010 SJ Web Edition\n# Date created = 19:35:13  July 19, 2013\n#\n# -------------------------------------------------------------------------- #\n\nQUARTUS_VERSION = \"10.1\"\nDATE = \"19:35:13  July 19, 2013\"\n\n# Revisions\n\nPROJECT_REVISION = \"ltcminer\"\nPROJECT_REVISION = \"ltcaminer\"\n"
  },
  {
    "path": "DE2-115-Single/ltcminer.qsf",
    "content": "# -------------------------------------------------------------------------- #\n#\n# Copyright (C) 1991-2010 Altera Corporation\n# Your use of Altera Corporation's design tools, logic functions\n# and other software and tools, and its AMPP partner logic\n# functions, and any output files from any of the foregoing\n# (including device programming or simulation files), and any\n# associated documentation or information are expressly subject\n# to the terms and conditions of the Altera Program License\n# Subscription Agreement, Altera MegaCore Function License\n# Agreement, or other applicable license agreement, including,\n# without limitation, that your use is for the sole purpose of\n# programming logic devices manufactured by Altera and sold by\n# Altera or its authorized distributors.  Please refer to the\n# applicable agreement for further details.\n#\n# -------------------------------------------------------------------------- #\n#\n# Quartus II\n# Version 10.0 Build 262 08/18/2010 Service Pack 1 SJ Web Edition\n# Date created = 05:05:52  March 02, 2011\n#\n# -------------------------------------------------------------------------- #\n#\n# Notes:\n#\n# 1) The default values for assignments are stored in the file:\n#    If this file doesn't exist, see file:\n#\t\tassignment_defaults.qdf\n#\n# 2) Altera recommends that you do not modify this file. This\n#    file is updated automatically by the Quartus II software\n#    and any changes you make may be lost or overwritten.\n#\n# -------------------------------------------------------------------------- #\n\n\nset_global_assignment -name FAMILY \"Cyclone IV E\"\nset_global_assignment -name DEVICE EP4CE115F29C7\nset_global_assignment -name TOP_LEVEL_ENTITY ltcminer\nset_global_assignment -name ORIGINAL_QUARTUS_VERSION \"10.0 SP1\"\nset_global_assignment -name PROJECT_CREATION_TIME_DATE \"17:52:09  MAY 05, 2011\"\nset_global_assignment -name LAST_QUARTUS_VERSION 10.1\nset_global_assignment -name MIN_CORE_JUNCTION_TEMP 0\nset_global_assignment -name MAX_CORE_JUNCTION_TEMP 85\nset_global_assignment -name DEVICE_FILTER_SPEED_GRADE 7\nset_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1\nset_global_assignment -name STRATIX_DEVICE_IO_STANDARD \"2.5 V\"\nset_location_assignment PIN_Y2 -to osc_clk\nset_instance_assignment -name IO_STANDARD \"3.3-V LVTTL\" -to osc_clk\nset_global_assignment -name ENABLE_SIGNALTAP OFF\nset_global_assignment -name POWER_PRESET_COOLING_SOLUTION \"23 MM HEAT SINK WITH 200 LFPM AIRFLOW\"\nset_global_assignment -name POWER_BOARD_THERMAL_MODEL \"NONE (CONSERVATIVE)\"\nset_global_assignment -name ALLOW_ANY_RAM_SIZE_FOR_RECOGNITION ON\nset_global_assignment -name ALLOW_ANY_SHIFT_REGISTER_SIZE_FOR_RECOGNITION ON\nset_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top\nset_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top\nset_global_assignment -name PARTITION_COLOR 16764057 -section_id Top\nset_global_assignment -name LL_ROOT_REGION ON -section_id \"Root Region\"\nset_global_assignment -name LL_MEMBER_STATE LOCKED -section_id \"Root Region\"\nset_global_assignment -name PROJECT_OUTPUT_DIRECTORY quartus_output\nset_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON\nset_global_assignment -name ALLOW_ANY_ROM_SIZE_FOR_RECOGNITION ON\nset_global_assignment -name EDA_SIMULATION_TOOL \"<None>\"\nset_global_assignment -name EDA_MAP_ILLEGAL_CHARACTERS OFF -section_id eda_simulation\nset_global_assignment -name EDA_TIME_SCALE \"1 ps\" -section_id eda_simulation\nset_global_assignment -name EDA_OUTPUT_DATA_FORMAT NONE -section_id eda_simulation\nset_global_assignment -name EDA_ENABLE_GLITCH_FILTERING OFF -section_id eda_simulation\nset_global_assignment -name EDA_WRITE_NODES_FOR_POWER_ESTIMATION OFF -section_id eda_simulation\nset_global_assignment -name EDA_TEST_BENCH_DESIGN_INSTANCE_NAME moogerfoogin -section_id eda_simulation\nset_global_assignment -name POWER_USE_PVA OFF\nset_global_assignment -name POWER_DEFAULT_TOGGLE_RATE 65%\nset_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF\nset_global_assignment -name VERILOG_FILE \"../source/ltcminer.v\"\nset_global_assignment -name VERILOG_FILE \"../source/hashcore.v\"\nset_global_assignment -name VERILOG_FILE \"../source/altera_ram.v\"\nset_global_assignment -name VERILOG_FILE \"../source/salsa.v\"\nset_global_assignment -name VERILOG_FILE \"../source/sha256_transform.v\"\nset_global_assignment -name VERILOG_FILE \"../source/sha-256-functions.v\"\nset_global_assignment -name VERILOG_FILE \"../source/altera_pll.v\"\nset_global_assignment -name VERILOG_FILE \"../source/altera_virtual_wire.v\"\nset_global_assignment -name VERILOG_MACRO \"NOLEDS=1\"\nset_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top"
  },
  {
    "path": "DE2-115-Single/ltcminer.sdc",
    "content": "##\n#\n# Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n#\n#\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n# \n##\n\ncreate_clock -period 20.000 -name osc_clk osc_clk\n\nderive_pll_clocks\nderive_clock_uncertainty\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/README.txt",
    "content": "Mining software for ltcminer.\n\nYou will need to install python 2.7, then ...\n\nFrom the fpgaminer/project/Verilog_Xilinx_Port/README.txt I quote ...\n  It requires a few non-standard libraries, pyserial and json-rpc.\n  http://pyserial.sourceforge.net/\n  (also generally available in Linux distributions)\n  http://json-rpc.org/wiki/python-json-rpc\n\nSince these are open source, I have included them in the MiningSoftware folder, vis\n\npyserial-2.6 from http://pyserial.sourceforge.net\npython-json-rpc from http://json-rpc.org/browser/trunk/python-jsonrpc/jsonrpc\n\nTo install them run \"python setup.py install\" in each folder (sudo if on linux)\n\nEdit ltcminer.py and set the serial port to match your system (eg COM2) plus\nyour pool url, worker name and worker password. You can also change the baudrate\nbut this must match the value hard-coded into ltcminer_icarus.v\n\nThere is a test getwork that you can enable, just uncomment the two lines for\ntest_payload. This still requires a working pool, which will REJECT the share, but\nits a useful quick test that everything is working. This is now obsolete as I have\nprovided ltcminer-testmode.py which runs 10 test hashes (a full 910 test hash set is\nalso available in ../../scripts/test_data_cut.txt).\n\nThe scripts take a single (optional) parameter, the clock speed (in MHz) for use with\nthe dynamic clock PLL. The value is checked for validity in the FPGA, so not all values\nwill work (see SPEED_LIMIT and SPEED_MIN parameters in ltcminer_icarus.v). Use the\nFLASHCLOCK feature (blinks the TxD led in time to the clock) to verify the clock speed\nhas been accepted.\n\nBe careful of spaces/tabs in python as these are part of the syntax! If you run\ninto problems making changes, just copy a previous line EXACTLY, then modify the part\nafter the initial spaces/tabs. ADDENDUM. I have now tabbified the script with tabstop=4\n(using Notepad++) which should make it much easier to edit.\n\nWhen using a stratum proxy server, follow the instructions at ...\nhttps://www.litecoinpool.org/help\n\nSpecifically you must use the version from ...\nhttps://github.com/CryptoManiac/stratum-mining-proxy\n\nStart it as follows (on linux) ...\n./mining_proxy.py -nm -pa scrypt -o litecoinpool.org -p 3333\n\nOr in background with ...\nnohup ./mining_proxy.py -nm -pa scrypt -o litecoinpool.org -p 3333 >/tmp/stratum_ltc.log 2>&1&\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/ltcminer-testmode.py",
    "content": "#!/usr/bin/env python\n\n# by teknohog\n\n# Python wrapper for Xilinx Serial Miner\n\n# Host/user configuration is NOT USED in ltcminer-testmode.py\n\n# CONFIGURATION - CHANGE THIS (eg try COM1, COM2, COM3, COM4 etc)\nserial_port = \"COM4\"\n# serial_port = \"/dev/ttyUSB0\"\t# raspberry pi\n\n# CONFIGURATION - how often to refresh work - reduced for testing\naskrate = 2\n\n###############################################################################\n\nfrom jsonrpc import ServiceProxy\nfrom time import ctime, sleep, time\nfrom serial import Serial\nfrom threading import Thread, Event\nfrom Queue import Queue\nimport sys\n\ndynclock = 0\ndynclock_hex = \"0000\"\n\ndef stats(count, starttime):\n\tkhshare = 65.536 * writer.diff\n\n\ts = sum(count)\n\ttdelta = time() - starttime\n\trate = s * khshare / tdelta\n\n\t# This is only a rough estimate of the true hash rate,\n\t# particularly when the number of events is low. However, since\n\t# the events follow a Poisson distribution, we can estimate the\n\t# standard deviation (sqrt(n) for n events). Thus we get some idea\n\t# on how rough an estimate this is.\n\n\t# s should always be positive when this function is called, but\n\t# checking for robustness anyway\n\tif s > 0:\n\t\tstddev = rate / s**0.5\n\telse:\n\t\tstddev = 0\n\n\treturn \"[%i accepted, %i failed, %.2f +/- %.2f khash/s]\" % (count[0], count[1], rate, stddev)\n\nclass Reader(Thread):\n\tdef __init__(self):\n\t\tThread.__init__(self)\n\n\t\tself.daemon = True\n\n\t\t# flush the input buffer\n\t\tser.read(1000)\n\n\tdef run(self):\n\t\twhile True:\n\t\t\tnonce = ser.read(4)\n\n\t\t\tif len(nonce) == 4:\n\t\t\t\t# Keep this order, because writer.block will be\n\t\t\t\t# updated due to the golden event.\n\t\t\t\tsubmitter = Submitter(writer.block, nonce)\n\t\t\t\tsubmitter.start()\n\t\t\t\tgolden.set()\n\n\nclass Writer(Thread):\n\tdef __init__(self,dynclock_hex):\n\t\tThread.__init__(self)\n\n\t\t# Keep something sensible available while waiting for the\n\t\t# first getwork\n\t\tself.block = \"0\" * 256\n\t\tself.target = \"f\" * 56 + \"ff070000\"\t\t# diff=32 for testmode\n\t\tself.diff = 32\t# testmode\n\t\tself.dynclock_hex = dynclock_hex\n\n\t\tself.daemon = True\n\t\tself.go = True\n\t\t# Alternatively use test_data_cut.txt for full 910 hash test suite\n\t\tself.infile = open(\"../../scripts/test_data.txt\",\"r\")\n\t\tself.nonce = 0\n\t\tself.nonce_tested = 0\n\t\tself.nonce_ok = 0\n\t\tself.nonce_fail = 0\n\n\tdef run(self):\n\t\twhile self.go:\n\t\t\ttry:\n\t\t\t\t# work = bitcoin.getwork()\n\t\t\t\t# self.block = work['data']\n\t\t\t\t# self.target = work['target']\n\t\t\t\tprint \"Tested\", self.nonce_tested, \" passed\", self.nonce_ok, \" fail\", self.nonce_fail, \" unmatched\", self.nonce_tested - self.nonce_ok - self.nonce_fail\n\t\t\t\tself.line = self.infile.readline()\n\t\t\t\tif (len(self.line) != 257):\n\t\t\t\t\tprint \"EOF on test data\"\t# Or its an error, but let's not be worrysome\n\n\t\t\t\t\t# quit()\t\t# Except it doesn't ...\n\t\t\t\t\tself.go = False\t# Terminating threads is a bit tricksy\n\t\t\t\t\tbreak\n\t\t\t\tself.nonce_tested = self.nonce_tested + 1\n\t\t\t\tself.block = self.line.rstrip()\n\t\t\t\t\n\t\t\t\t# Hard-code a diff=32 target for test work\n\t\t\t\t# Replace MSB 16 bits of target with clock (NB its reversed)\n\t\t\t\tself.target = \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07\" + self.dynclock_hex\n\t\t\t\tself.dynclock_hex = \"0000\"\t# Once only\n\t\t\t\t\n\t\t\t\t# print(\"block old \" + self.block)\n\t\t\t\t# We need to subtract a few from the nonces in order to match (why?)\n\t\t\t\tnonce_bin = self.block.decode('hex')[79:75:-1]\n\t\t\t\tself.nonce = int(nonce_bin.encode('hex'), 16)\n\t\t\t\t# print \"nonce old =\", self.nonce\n\t\t\t\tnonce_new = self.nonce - 50\n\t\t\t\tif (nonce_new < 0):\n\t\t\t\t\tnonce_new = 0\n\t\t\t\t# print \"nonce new =\", nonce_new\n\t\t\t\tnonce_hex = \"{0:08x}\".format(nonce_new)\n\t\t\t\t# print \"encoded = \", nonce_hex\n\t\t\t\tnonce_hex_rev = nonce_hex[6:8]+nonce_hex[4:6]+nonce_hex[2:4]+nonce_hex[0:2]\n\t\t\t\t# print \"reversed = \", nonce_hex_rev\n\t\t\t\tself.block = self.block[0:152]+nonce_hex_rev+self.block[160:]\n\t\t\t\t# print(\"block new \" + self.block)\n\t\t\texcept:\n\t\t\t\tprint(\"RPC getwork error\")\n\t\t\t\t# In this case, keep crunching with the old data. It will get \n\t\t\t\t# stale at some point, but it's better than doing nothing.\n\n\t\t\t# print(\"block \" + self.block + \" target \" + self.target)\t# DEBUG\n\n\t\t\tsdiff = self.target.decode('hex')[31:27:-1]\n\t\t\tintTarget = int(sdiff.encode('hex'), 16)\n\t\t\tif (intTarget < 1):\n\t\t\t\tprint \"WARNING zero target\", intTarget\n\t\t\t\tprint \"target\", self.target\n\t\t\t\tprint(\"sdiff\", sdiff)\t# NB Need brackets here else prints binary\n\t\t\t\tself.target = \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000\"\n\t\t\telse:\n\t\t\t\tnewdiff = 65536.0 / (intTarget+1)\n\t\t\t\tif (self.diff != newdiff):\n\t\t\t\t\tprint \"New target diff =\", newdiff\n\t\t\t\tself.diff = newdiff\n\n\t\t\t# print(\"Sending data to FPGA\")\t# DEBUG\n\n\t\t\t# for litecoin send 80 bytes of the 128 byte data plus 4 bytes of 32 byte target\n\t\t\tpayload = self.target.decode('hex')[31:27:-1] + self.block.decode('hex')[79::-1]\n\t\t\t\n\t\t\t# TEST HASH, this should match on nonce 0000318f\n\t\t\t# NB The pool will REJECT this share as it did not send the data...\n\t\t\t# UNCOMMENT the following two lines for testing...\n\t\t\t# test_payload =\"000000014eb4577c82473a069ca0e95703254da62e94d1902ab6f0eae8b1e718565775af20c9ba6ced48fc9915ef01c54da2200090801b2d2afc406264d491c7dfc7b0b251e91f141b44717e00310000ff070000\"\n\t\t\t# payload = test_payload.decode('hex')[::-1]\n\n\t\t\t# This is probably best commented out unless debugging ...\n\t\t\tprint(\"Test \" + payload.encode('hex_codec'))\t# DEBUG\n\t\t\t\n\t\t\tser.write(payload)\n\t\t\t\n\t\t\tresult = golden.wait(askrate)\n\n\t\t\tif result:\n\t\t\t\tgolden.clear()\n\nclass Submitter(Thread):\n\tdef __init__(self, block, nonce):\n\t\tThread.__init__(self)\n\n\t\tself.block = block\n\t\tself.nonce = nonce\n\n\tdef run(self):\n\t\t# This thread will be created upon every submit, as they may\n\t\t# come in sooner than the submits finish.\n\n\t\t# print(\"Block found on \" + ctime())\n\t\tprint(\"Share found on \" + ctime() + \" nonce \" + self.nonce.encode('hex_codec'))\n\t\tif (int(self.nonce.encode('hex_codec'),16) != writer.nonce):\n\t\t\tprint \"... ERROR expected nonce\", hex(writer.nonce)\n\t\t\twriter.nonce_fail = writer.nonce_fail + 1\n\t\telse:\n\t\t\tprint \"... CORRECT\"\n\t\t\twriter.nonce_ok = writer.nonce_ok + 1\n\t\t\n\t\thrnonce = self.nonce[::-1].encode('hex')\n\n\t\tdata = self.block[:152] + hrnonce + self.block[160:]\n\n\t\ttry:\n\t\t\t# result = bitcoin.getwork(data)\n\t\t\tresult = False\n\t\t\t# print(\"Upstream result: \" + str(result))\t# Pointless in test mode\n\t\texcept:\n\t\t\tprint(\"RPC send error\")\n\t\t\t# a sensible boolean for stats\n\t\t\tresult = False\n\n\t\tresults_queue.put(result)\n\nclass Display_stats(Thread):\n\tdef __init__(self):\n\t\tThread.__init__(self)\n\n\t\tself.count = [0, 0]\n\t\tself.starttime = time()\n\t\tself.daemon = True\n\n\t\tprint(\"Miner started on \" + ctime())\n\n\tdef run(self):\n\t\twhile True:\n\t\t\tresult = results_queue.get()\n\t\t\t\n\t\t\tif result:\n\t\t\t\tself.count[0] += 1\n\t\t\telse:\n\t\t\t\tself.count[1] += 1\n\t\t\t\t\n\t\t\t# print(stats(self.count, self.starttime)) \t# Pointless in test mode\n\t\t\t\t\n\t\t\tresults_queue.task_done()\n\n# ======= main =======\n\n# Process command line\n\nif (len(sys.argv) > 2):\n\tprint \"ERROR too many command line arguments\"\n\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\tquit()\n\nif (len(sys.argv) == 1):\n\tprint \"WARNING no clockfreq supplied, not setting freq\"\nelse:\n\t# TODO ought to check the value is a valid integer\n\ttry:\n\t\tdynclock = int(sys.argv[1])\n\texcept:\n\t\tprint \"ERROR parsing clock frequency on command line, needs to be an integer\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tif (dynclock==0):\n\t\tprint \"ERROR parsing clock frequency on command line, cannot be zero\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tif (dynclock>254):\t# Its 254 since onescomplement(255) is zero, which is not allowed\n\t\tprint \"ERROR parsing clock frequency on command line, max 254\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tif (dynclock<25):\n\t\tprint \"ERROR use at least 25 for clock (the DCM can lock up for low values)\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tdynclock_hex = \"{0:04x}\".format((255-dynclock)*256+dynclock)\t# both value and ones-complement\n\tprint \"INFO will set clock to\", dynclock, \"MHz hex\", dynclock_hex\n\ngolden = Event()\n\n# url = 'http://' + user + ':' + password + '@' + host + ':' + http_port\n\n# bitcoin = ServiceProxy(url)\n\nresults_queue = Queue()\n\n# default is 8 bit no parity which is fine ...\n# http://pyserial.sourceforge.net/shortintro.html#opening-serial-ports\n\nser = Serial(serial_port, 115200, timeout=askrate)\n\nreader = Reader()\nwriter = Writer(dynclock_hex)\ndisp = Display_stats()\n\nreader.start()\nwriter.start()\ndisp.start()\n\ntry:\n\twhile writer.go:\n\t\t# Threads are generally hard to interrupt. So they are left\n\t\t# running as daemons, and we do something simple here that can\n\t\t# be easily terminated to bring down the entire script.\n\t\tsleep(1)\nexcept KeyboardInterrupt:\n\tprint(\"Terminated\")\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/ltcminer.py",
    "content": "#!/usr/bin/env python\n\n# by teknohog\n\n# Python wrapper for Xilinx Serial Miner\n\n# CONFIGURATION - CHANGE THIS TO YOUR ACCOUNT DETAILS ...\n# Optionally install a Stratum Proxy Server\n\nhost = \"mining-foreman.org\"\t\t\t# Getwork pools\n# host = \"http://litecoinpool.org\"\n# host = \"localhost\"\t# Stratum Proxy on localhost\n# host = \"tvpi.lan\"\t\t# Stratum Proxy (raspberry pi)\n\nhttp_port = \"10341\"\t\t# Getwork port (mining-foreman)\n# http_port = \"9332\"\t# Getwork port (litcoinpool)\n# http_port = \"8332\"\t# Getwork port (stratum)\n\nuser = \"username.1\"\t\t# Your worker goes here\npassword = \"password\"\t# Worker password, NOT your account password\n\n# CONFIGURATION - CHANGE THIS (eg try COM1, COM2, COM3, COM4 etc)\nserial_port = \"COM4\"\n# serial_port = \"/dev/ttyUSB0\"\t# raspberry pi\n\n# CONFIGURATION - how often to refresh work. 20 seconds is fine, but work is\n# not initially fetched until this timeout expires. Reduce it for debugging\n# and for stratum (2 works fine).\naskrate = 20\t# Getwork\n# askrate = 2\t# Stratum\n\n###############################################################################\n\nfrom jsonrpc import ServiceProxy\nfrom time import ctime, sleep, time\nfrom serial import Serial\nfrom threading import Thread, Event\nfrom Queue import Queue\nimport sys\n\ndynclock = 0\ndynclock_hex = \"0000\"\n\ndef stats(count, starttime):\n\tkhshare = 65.536 * writer.diff\n\n\ts = sum(count)\n\ttdelta = time() - starttime\n\trate = s * khshare / tdelta\n\n\t# This is only a rough estimate of the true hash rate,\n\t# particularly when the number of events is low. However, since\n\t# the events follow a Poisson distribution, we can estimate the\n\t# standard deviation (sqrt(n) for n events). Thus we get some idea\n\t# on how rough an estimate this is.\n\n\t# s should always be positive when this function is called, but\n\t# checking for robustness anyway\n\tif s > 0:\n\t\tstddev = rate / s**0.5\n\telse:\n\t\tstddev = 0\n\n\treturn \"[%i accepted, %i failed, %.2f +/- %.2f khash/s]\" % (count[0], count[1], rate, stddev)\n\nclass Reader(Thread):\n\tdef __init__(self):\n\t\tThread.__init__(self)\n\n\t\tself.daemon = True\n\n\t\t# flush the input buffer\n\t\tser.read(1000)\n\n\tdef run(self):\n\t\twhile True:\n\t\t\tnonce = ser.read(4)\n\n\t\t\tif len(nonce) == 4:\n\t\t\t\t# Keep this order, because writer.block will be\n\t\t\t\t# updated due to the golden event.\n\t\t\t\tsubmitter = Submitter(writer.block, nonce)\n\t\t\t\tsubmitter.start()\n\t\t\t\tgolden.set()\n\n\nclass Writer(Thread):\n\tdef __init__(self,dynclock_hex):\n\t\tThread.__init__(self)\n\n\t\t# Keep something sensible available while waiting for the\n\t\t# first getwork\n\t\tself.block = \"0\" * 256\n\t\t# self.target = \"f\" * 56 + \"ff070000\"\t\t# diff=32\n\t\tself.target = \"f\" * 56 + \"ff7f0000\"\t\t\t# diff=2\n\t\tself.diff = 2.0\t# NB This is updated from target (default 2 is safer than 32 to avoid losing shares)\n\t\tself.dynclock_hex = dynclock_hex\n\n\t\tself.daemon = True\n\n\tdef run(self):\n\t\twhile True:\n\t\t\ttry:\n\t\t\t\twork = bitcoin.getwork()\n\t\t\t\tself.block = work['data']\n\t\t\t\tself.target = work['target']\n\t\t\texcept:\n\t\t\t\tprint(\"RPC getwork error\")\n\t\t\t\t# In this case, keep crunching with the old data. It will get \n\t\t\t\t# stale at some point, but it's better than doing nothing.\n\n\t\t\t# print(\"block \" + self.block + \" target \" + self.target)\t# DEBUG\n\n\t\t\tsdiff = self.target.decode('hex')[31:27:-1]\n\t\t\tintTarget = int(sdiff.encode('hex'), 16)\n\t\t\tif (intTarget < 1):\n\t\t\t\tprint \"WARNING zero target, defaulting to diff=2\", intTarget\n\t\t\t\tprint \"target\", self.target\n\t\t\t\tprint(\"sdiff\", sdiff)\t# NB Need brackets here else prints binary\n\t\t\t\tself.target = \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000\"\n\t\t\telse:\n\t\t\t\tnewdiff = 65536.0 / (intTarget+1)\n\t\t\t\tif (self.diff != newdiff):\n\t\t\t\t\tprint \"New target diff =\", newdiff\n\t\t\t\tself.diff = newdiff\n\n\t\t\t# Replace MSB 16 bits of target with clock (NB its reversed)\n\t\t\tself.target = self.target[0:60] + self.dynclock_hex\n\t\t\tself.dynclock_hex = \"0000\"\t# Once only\n\t\t\t\n\t\t\tprint(\"Sending data to FPGA\")\t# DEBUG\n\n\t\t\t# for litecoin send 80 bytes of the 128 byte data plus 4 bytes of 32 byte target\n\t\t\tpayload = self.target.decode('hex')[31:27:-1] + self.block.decode('hex')[79::-1]\n\t\t\t\n\t\t\t# TEST HASH, this should match on nonce 0000318f\n\t\t\t# NB The pool will REJECT this share as it did not send the data...\n\t\t\t# UNCOMMENT the following two lines for testing...\n\t\t\t# test_payload =\"000000014eb4577c82473a069ca0e95703254da62e94d1902ab6f0eae8b1e718565775af20c9ba6ced48fc9915ef01c54da2200090801b2d2afc406264d491c7dfc7b0b251e91f141b44717e00310000ff070000\"\n\t\t\t# payload = test_payload.decode('hex')[::-1]\n\n\t\t\tprint(\"Payload \" + payload.encode('hex_codec'))\t# DEBUG\n\t\t\t\n\t\t\tser.write(payload)\n\t\t\t\n\t\t\tresult = golden.wait(askrate)\n\n\t\t\tif result:\n\t\t\t\tgolden.clear()\n\nclass Submitter(Thread):\n\tdef __init__(self, block, nonce):\n\t\tThread.__init__(self)\n\n\t\tself.block = block\n\t\tself.nonce = nonce\n\n\tdef run(self):\n\t\t# This thread will be created upon every submit, as they may\n\t\t# come in sooner than the submits finish.\n\n\t\t# print(\"Block found on \" + ctime())\n\t\tprint(\"Share found on \" + ctime() + \" nonce \" + self.nonce.encode('hex_codec'))\n\t\t\n\t\thrnonce = self.nonce[::-1].encode('hex')\n\n\t\tdata = self.block[:152] + hrnonce + self.block[160:]\n\n\t\ttry:\n\t\t\tresult = bitcoin.getwork(data)\n\t\t\tprint(\"Upstream result: \" + str(result))\n\t\texcept:\n\t\t\tprint(\"RPC send error\")\n\t\t\t# a sensible boolean for stats\n\t\t\tresult = False\n\n\t\tresults_queue.put(result)\n\nclass Display_stats(Thread):\n\tdef __init__(self):\n\t\tThread.__init__(self)\n\n\t\tself.count = [0, 0]\n\t\tself.starttime = time()\n\t\tself.daemon = True\n\n\t\tprint(\"Miner started on \" + ctime())\n\n\tdef run(self):\n\t\twhile True:\n\t\t\tresult = results_queue.get()\n\t\t\t\n\t\t\tif result:\n\t\t\t\tself.count[0] += 1\n\t\t\telse:\n\t\t\t\tself.count[1] += 1\n\t\t\t\t\n\t\t\tprint(stats(self.count, self.starttime))\n\t\t\t\t\n\t\t\tresults_queue.task_done()\n\n# ======= main =======\n\n# Process command line\n\nif (len(sys.argv) > 2):\n\tprint \"ERROR too many command line arguments\"\n\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\tquit()\n\nif (len(sys.argv) == 1):\n\tprint \"WARNING no clockfreq supplied, not setting freq\"\nelse:\n\t# TODO ought to check the value is a valid integer\n\ttry:\n\t\tdynclock = int(sys.argv[1])\n\texcept:\n\t\tprint \"ERROR parsing clock frequency on command line, needs to be an integer\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tif (dynclock==0):\n\t\tprint \"ERROR parsing clock frequency on command line, cannot be zero\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tif (dynclock>254):\t# Its 254 since onescomplement(255) is zero, which is not allowed\n\t\tprint \"ERROR parsing clock frequency on command line, max 254\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tif (dynclock<25):\n\t\tprint \"ERROR use at least 25 for clock (the DCM can lock up for low values)\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tdynclock_hex = \"{0:04x}\".format((255-dynclock)*256+dynclock)\t# both value and ones-complement\n\tprint \"INFO will set clock to\", dynclock, \"MHz hex\", dynclock_hex\n\ngolden = Event()\n\nurl = 'http://' + user + ':' + password + '@' + host + ':' + http_port\n\nbitcoin = ServiceProxy(url)\n\nresults_queue = Queue()\n\n# default is 8 bit no parity which is fine ...\n# http://pyserial.sourceforge.net/shortintro.html#opening-serial-ports\n\nser = Serial(serial_port, 115200, timeout=askrate)\n\nreader = Reader()\nwriter = Writer(dynclock_hex)\ndisp = Display_stats()\n\nreader.start()\nwriter.start()\ndisp.start()\n\ntry:\n\twhile True:\n\t\t# Threads are generally hard to interrupt. So they are left\n\t\t# running as daemons, and we do something simple here that can\n\t\t# be easily terminated to bring down the entire script.\n\t\tsleep(10000)\nexcept KeyboardInterrupt:\n\tprint(\"Terminated\")\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/CHANGES.txt",
    "content": "========================\n pySerial Release Notes\n========================\n\nVersion 1.0     13 Feb 2002\n---------------------------\n- First public release.\n- Split from the pybsl application (see http://mspgcc.sourceforge.net)\n\nNew Features:\n\n- Added Jython support\n\n\nVersion 1.1     14 Feb 2002\n---------------------------\nBugfixes:\n\n- Win32, when not specifying a timeout\n- Typos in the Docs\n\nNew Features:\n\n- added ``serialutil`` which provides a base class for the ``Serial``\n  objects.\n\n- ``readline``, ``readlines``, ``writelines`` and ``flush`` are now supported\n  see README.txt for deatils.\n\n\nVersion 1.11    14 Feb 2002\n---------------------------\nSame as 1.1 but added missing files.\n\n\nVersion 1.12    18 Feb 2002\n---------------------------\nRemoved unneded constants to fix RH7.x problems.\n\n\nVersion 1.13    09 Apr 2002\n---------------------------\nAdded alternate way for enabling rtscts (CNEW_RTSCTS is tried too)\nIf port opening fails, a ``SerialException`` is raised on all platforms\n\n\nVersion 1.14    29 May 2002\n---------------------------\nAdded examples to archive\nAdded non-blocking mode for ``timeout=0`` (tnx Mat Martineau)\n\nBugfixes:\n\n- win32 does now return the remaining characters on timeout\n\n\nVersion 1.15    04 Jun 2002\n---------------------------\nBugfixes (win32):\n\n- removed debug messages\n- compatibility to win9x improved\n\n\nVersion 1.16    02 Jul 2002\n---------------------------\nAdded implementation of RI and corrected RTS/CTS on Win32\n\n\nVersion 1.17    03 Jul 2002\n---------------------------\nSilly mix of two versions in win32 code corrected\n\n\nVersion 1.18    06 Dec 2002\n---------------------------\nBugfixes (general):\n\n- remove the mapping of flush to the destructive flushOutput as\n  this is not the expected behaviour.\n- readline: EOL character for lines can be chosen idea by \n  John Florian.\n\nBugfixes (posix):\n\n- cygwin port numbering fixed\n- test each and every constant for it's existence in termios module,\n  use default if not existent (fix for Bug item #640214)\n- wrong exception on nonexistent ports with /dev file. bug report\n  by Louis Cordier\n\nBugfixes (win32):\n\n- RTS/CTS handling as suggested in Bug #635072\n- bugfix of timeouts brought up by Markus Hoffrogge\n\n\nVersion 1.19    19 Mar 2003\n---------------------------\nBugfixes (posix):\n\n- removed ``dgux`` entry which actually had a wrong comment and is\n  probably not in use anywhere.\n\nBugfixes (win32):\n\n- added ``int()`` conversion, [Bug 702120]\n- remove code to set control lines in close method of win32\n  version. [Bug 669625]\n\n\nVersion 1.20    28 Aug 2003\n---------------------------\n- Added ``serial.device()`` for all platforms\n\nBugfixes (win32):\n\n- don't recreate overlapped structures and events on each\n  read/write.\n- don't set unneeded event masks.\n- dont use DOS device names for ports > 9.\n- remove send timeout (its not used in the linux impl. anyway).\n\n\nVersion 1.21    30 Sep 2003\n---------------------------\nBugfixes (win32):\n\n- name for COM10 was not built correctly, found by Norm Davis.\n\nBugfixes (examples):\n\n- small change in ``miniterm.py`` that should mage it run on cygwin,\n  [Bug 809904] submitted by Rolf Campbell.\n\n\nVersion 2.0b1    1 Oct 2003\n---------------------------\nTransition to the Python 2.0 series:\n\n- New implementation only supports Python 2.2+, backwards compatibility\n  should be maintained almost everywhere.\n  The OS handles (like the ``hComPort`` or ``fd`` attribute) were prefixed\n  with an underscore. The different names stay, as anyone that uses one of\n  these has to write platform specific code anyway.\n- Common base class ``serialutil.SerialBase`` for all implementations.\n- ``PARITY_NONE``, ``PARITY_EVEN``, ``PARITY_ODD`` constants changed and all\n  these constants moved to ``serialutil.py`` (still available as\n  ``serial.PARITY_NONE`` etc. and they should be used that way)\n- Added ``serial.PARITY_NAMES`` (implemented in ``serialutil.PARITY_NAMES``).\n  This dictionary can be used to convert parity constants to meaningful\n  strings.\n- Each Serial class and instance has a list of supported values:\n  ``BAUDRATES``, ``BYTESIZES``, ``PARITIES``, ``STOPBITS``Ggg\n  (i.e. ``serial.Serial.BAUDRATES or s = serial.Serial; s.BAUDRATES``)\n  these values can be used to fill in value sin GUI dialogs etc.\n- Creating a ``Serial()`` object without port spec returns an unconfigured,\n  closed port. Useful if a GUI dialog should take a port and configure\n  it.\n- New methods for ``serial.Serial`` instances: ``open()``, ``isOpen()``\n- A port can be opened and closed as many times as desired.\n- Instances of ``serial.Serial`` have ``baudrate``, ``bytesize``, ``timeout``\n  etc. attributes implemented as properties, all can be set while the port is\n  opened. It will then be reconfigured.\n- Improved ``__doc__``'s.\n- New ``test_advanced.py`` for the property setting/getting testing.\n- Small bugfix on posix with get* methods (return value should be true a\n  boolean).\n- added a ``__repr__`` that returns a meaningful string will all the serial\n  setting, easy for debugging.\n- The serialposix module does not throw an exception on unsupported\n  platforms, the message is still printed. The idea that it may still\n  work even if the platform itself s not known, it simply tries to do\n  the posix stuff anyway (It's likely that opening ports by number\n  fails, but by name it should work).\n\n\nVersion 2.0b2    4 Oct 2003\n---------------------------\n- Added serial port configuration dialog for wxPython to the examples.\n- Added terminal application for wxPython with wxGlade design file\n  to the examples.\n- Jython support is currently broken as Jython does not have a Python 2.2\n  compatible release out yet\n\n\nVersion 2.0      6 Nov 2003\n---------------------------\n- Fixes ``setup.py`` for older distutils\n\n\nVersion 2.1     28 Jul 2004\n---------------------------\nBugfixes:\n\n- Fix XON/XOFF values [Bug 975250]\n\nBugfixes (posix):\n\n- ``fd == 0`` fix from Vsevolod Lobko\n- netbsd fixes from Erik Lindgren\n- Dynamicaly lookup baudrates and some cleanups\n\nBugfixes (examples):\n\n- CRLF handling of ``miniterm.py`` should be more consistent on Win32\n  and others. Added LF only command line option\n- Multithreading fixes to ``wxTerminal.py`` (helps with wxGTK)\n- Small change for wxPython 2.5 in ``wxSerialConfigDialog.py`` [Bug 994856]\n\nNew Features:\n\n- Implement write timeouts (``writeTimeout`` parameter)\n\n\nVersion 2.2     31 Jul 2005\n---------------------------\nBugfixes:\n\n- [Bug 1014227]: property <del> broken\n- [Bug 1105687]: ``serial_tcp_example.py``: ``--localport`` option\n- [Bug 1106313]: device (port) strings cannot be unicode\n\nBugfixes (posix):\n\n- [Patch 1043436] Fix for [Bug 1043420] (OSError: EAGAIN)\n- [Patch 1102700] ``fileno()`` added\n- ensure disabled PARMRK\n\nBugfixes (win32):\n\n- [Patch 983106]: keep RTS/CTS state on port setting changes\n\nNew Features:\n\n- ``dsrdtr`` setting to enable/disable DSR/DTR flow control independently\n  from the ``rtscts`` setting. (Currenly Win32 only, ignored on other\n  platforms)\n\n\nVersion 2.3     19 Jun 2008\n---------------------------\nNew Features:\n\n- iterator interface. ``for line in Serial(...): ...`` is now possible\n  Suggested by Bernhard Bender\n- ``sendBreak()`` accepts a ``duration`` argument. Default duration increased.\n- win32 handles \\\\.\\COMx format automatically for com ports of higher number\n  (COM10 is internally translated to \\\\.\\COM10 etc.)\n- miniterm.py has a new feature to send a file (upload) and configurable\n  special characters for exit and upload. Refactored internals to class based\n  structure (upload and class refactoring by Colin D Bennett)\n\nBugfixes:\n\n- [Bug 1451535] TCP/serial redirect example \"--help\"\n- update VERSION variable\n- update wxSerialConfigDialog.py and wxTerminal.py compatibility with\n  wxPython 2.8 (Peleg)\n- Check for string in write function. Using unicode causes errors, this\n  helps catching errors early (Tom Lynn)\n\nBugfixes (posix):\n\n- [Bug 1554183] setRTS/setDTR reference to non existing local \"on\"\n- [Bug 1513653] file descriptor not closed when exception is thrown\n- FreeBSD now uses cuadX instead of cuaaX (Patrick Phalen)\n\nBugfixes (win32):\n\n- [Bug 1520357] Handle leak\n- [Bug 1679013] Ignore exception raised by SetCommTimeout() in close().\n- [Bug 1938118] process hang forever under XP\n\n\nVersion 2.4      6 Jul 2008\n---------------------------\nNew Features:\n\n- [Patch 1616790] pyserial: Add inter-character timeout feature\n- [Patch 1924805] add a setBreak function\n- Add mark/space parity\n- Add .NET/Mono backend (IronPython)\n\nBugfixes (posix):\n\n- [Bug 1783159] Arbitrary baud rates (Linux/Posix)\n\nBugfixes (win32):\n\n- [Patch 1561423] Add mark/space parity, Win32\n- [Bug 2000771] serial port CANNOT be specified by number on windows\n- examples/scanwin32.py does no longer return \\\\.\\ names\n- fix \\\\.\\ handling for some cases\n\nBugfixes (jython):\n\n - The Jython backend tries javax.comm and gnu.io (Seo Sanghyeon)\n\n\nVersion 2.5-rc1  2009-07-30\n---------------------------\nNew Features:\n\n- Python 3.x support (through 2to3)\n- compatible with Python io library (Python 2.6+)\n- Support for Win32 is now written on the top of ctypes (bundled with\n  Python 2.5+) instead of pywin32 (patch by Giovanni Bajo).\n- 1.5 stop bits (STOPBITS_ONE_POINT_FIVE, implemented on all platforms)\n- miniterm application extended (CTRL+T -> menu)\n- miniterm.py is now installed as \"script\"\n- add scanlinux.py example\n- add port_publisher example\n- experimental RFC-2217 server support (examples/rfc2217_server.py)\n- add ``getSettingsDict`` and ``applySettingsDict`` serial object methods\n- use a ``poll`` based implementation on Posix, instead of a ``select`` based,\n  provides better error handling [removed again in later releases].\n\nBugfixes:\n\n- Improve and fix tcp_serial_redirector example.\n- [Bug 2603052] 5-bit mode (needs 1.5 stop bits in some cases)\n\nBugfixes (posix):\n\n- [Bug 2810169] Propagate exceptions raised in serialposix _reconfigure\n- [Bug 2562610] setting non standard baud rates on Darwin (Emmanuel Blot)\n\nBugfixes (win32):\n\n- [Bug 2469098] parity PARITY_MARK, PARITY_SPACE isn't supported on win32\n- [SF  2446218] outWaiting implemented\n- [Bug 2392892] scanwin32.py better exception handling\n- [Bug 2505422] scanwin32.py Vista 64bit compatibility\n\n\nVersion 2.5-rc2  2010-01-02\n---------------------------\nNew Features:\n\n- Documentation update, now written with Sphinx/ReST\n- Updated miniterm.py example\n- experimental RFC-2217 client support (serial.rfc2217.Serial, see docs)\n- add ``loop://`` device for testing.\n- add ``serial.serial_for_url`` factory function (support for native ports and\n  ``rfc2217``, ``socket`` and ``loop`` URLs)\n- add new example: ``rfc2217_server.py``\n- tests live in their own directory now (no longer in examples)\n\nBugfixes:\n\n- [Bug 2915810] Fix for suboption parsing in rfc2217\n- Packaging bug (missed some files)\n\nBugfixes (posix):\n\n- improve write timeout behavior\n- [Bug 2836297] move Linux specific constants to not break other platforms\n- ``poll`` based implementation for ``read`` is in a separate class\n  ``PosixPollSerial``, as it is not supported well on all platforms (the\n  default ``Serial`` class uses select).\n- changed error handling in ``read`` so that disconnected devices are\n  detected.\n\n\nBugfixes (win32):\n\n- [Bug 2886763] hComPort doesn't get initialized for Serial(port=None)\n\n\nVersion 2.5      2010-07-22\n---------------------------\nNew Features:\n\n- [Bug 2976262] dsrdtr should default to False\n  ``dsrdtr`` parameter default value changed from ``None`` (follow ``rtscts``\n  setting) to ``False``. This means ``rtscts=True`` enables hardware flow\n  control on RTS/CTS but no longer also on DTR/DSR. This change mostly\n  affects Win32 as on other platforms, that setting was ignored anyway.\n- Improved xreadlines, it is now a generator function that yields lines as they\n  are received (previously it called readlines which would only return all\n  lines read after a read-timeout). However xreadlines is deprecated an not\n  available when the io module is used. Use ``for line in Serial(...):``\n  instead.\n\nBugfixes:\n\n- [Bug 2925854] test.py produces exception with python 3.1\n- [Bug 3029812] 2.5rc2 readline(s) doesn't work\n\nBugfixes (posix):\n\n- [BUG 3006606] Nonblocking error - Unix platform\n\nBugfixes (win32):\n\n- [Bug 2998169] Memory corruption at faster transmission speeds.\n  (bug introduced in 2.5-rc1)\n\n\nVersion 2.6      2011-11-02\n---------------------------\nNew Features:\n\n- Moved some of the examples to serial.tools so that they can be used\n  with ``python -m``\n- serial port enumeration now included as ``serial.tools.list_ports``\n- URL handers for ``serial_for_url`` are now imported dynamically. This allows\n  to add protocols w/o editing files. The list\n  ``serial.protocol_handler_packages`` can be used to add or remove user\n  packages with protocol handlers (see docs for details).\n- new URL type: hwgrep://<regexp> uses list_ports module to search for ports\n  by their description\n- serveral internal changes to improve Python 3.x compatibility (setup.py,\n  use of absolute imports and more)\n\nBugfixes:\n\n- [Bug 3093882] calling open() on an already open port now raises an exception\n- [Bug 3245627] connection-lost let rfc2217 hangs in closed loop\n- [Patch 3147043] readlines() to support multi-character eol\n\nBugfixes (posix):\n\n- [Patch 3316943] Avoid unneeded termios.tcsetattr calls in serialposix.py\n- [Patch 2912349] Serial Scan as a Module with Mac Support\n\nBugfixes (win32):\n\n- [Bug 3057499] writeTimeoutError when write Timeout is 0\n- [Bug 3414327] Character out of range in list_ports_windows\n- [Patch 3036175] Windows 98 Support fix\n- [Patch 3054352] RTS automatic toggle, for RS485 functionality.\n- Fix type definitions for 64 bit Windows compatibility\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/LICENSE.txt",
    "content": "Copyright (c) 2001-2011 Chris Liechti <cliechti@gmx.net>;\nAll Rights Reserved.\n\nThis is the Python license. In short, you can use this product in\ncommercial and non-commercial applications, modify it, redistribute it.\nA notification to the author when you use and/or modify it is welcome.\n\n\nTERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING THIS SOFTWARE\n===================================================================\n\nLICENSE AGREEMENT\n-----------------\n\n1. This LICENSE AGREEMENT is between the copyright holder of this\nproduct, and the Individual or Organization (\"Licensee\") accessing\nand otherwise using this product in source or binary form and its\nassociated documentation.\n\n2. Subject to the terms and conditions of this License Agreement,\nthe copyright holder hereby grants Licensee a nonexclusive,\nroyalty-free, world-wide license to reproduce, analyze, test,\nperform and/or display publicly, prepare derivative works, distribute,\nand otherwise use this product alone or in any derivative version,\nprovided, however, that copyright holders License Agreement and\ncopyright holders notice of copyright are retained in this product\nalone or in any derivative version prepared by Licensee.\n\n3. In the event Licensee prepares a derivative work that is based on\nor incorporates this product or any part thereof, and wants to make\nthe derivative work available to others as provided herein, then\nLicensee hereby agrees to include in any such work a brief summary of\nthe changes made to this product.\n\n4. The copyright holder is making this product available to Licensee on\nan \"AS IS\" basis. THE COPYRIGHT HOLDER MAKES NO REPRESENTATIONS OR\nWARRANTIES, EXPRESS OR IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION,\nTHE COPYRIGHT HOLDER MAKES NO AND DISCLAIMS ANY REPRESENTATION OR\nWARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR\nTHAT THE USE OF THIS PRODUCT WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.\n\n5. THE COPYRIGHT HOLDER SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER\nUSERS OF THIS PRODUCT FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL\nDAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE\nUSING THIS PRODUCT, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE\nPOSSIBILITY THEREOF.\n\n6. This License Agreement will automatically terminate upon a material\nbreach of its terms and conditions.\n\n7. Nothing in this License Agreement shall be deemed to create any\nrelationship of agency, partnership, or joint venture between the\ncopyright holder and Licensee. This License Agreement does not grant\npermission to use trademarks or trade names from the copyright holder\nin a trademark sense to endorse or promote products or services of\nLicensee, or any third party.\n\n8. By copying, installing or otherwise using this product, Licensee\nagrees to be bound by the terms and conditions of this License\nAgreement.\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/MANIFEST.in",
    "content": "include README.txt\ninclude LICENSE.txt\ninclude CHANGES.txt\ninclude MANIFEST.in\ninclude setup.py\n\ninclude examples/enhancedserial.py\ninclude examples/miniterm.py\ninclude examples/port_publisher.py\ninclude examples/port_publisher.sh\ninclude examples/rfc2217_server.py\ninclude examples/scan.py\ninclude examples/scanlinux.py\ninclude examples/scanwin32.py\ninclude examples/setup-miniterm-py2exe.py\ninclude examples/setup-rfc2217_server-py2exe.py\ninclude examples/setup-wxTerminal-py2exe.py\ninclude examples/tcp_serial_redirect.py\ninclude examples/wxSerialConfigDialog.py\ninclude examples/wxSerialConfigDialog.wxg\ninclude examples/wxTerminal.py\ninclude examples/wxTerminal.wxg\n\ninclude test/run_all_tests.py\ninclude test/test.py\ninclude test/test_advanced.py\ninclude test/test_high_load.py\ninclude test/test_io_lib.py\ninclude test/test_readline.py\n\ninclude documentation/*.rst\ninclude documentation/pyserial.png\ninclude documentation/conf.py\ninclude documentation/Makefile\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/PKG-INFO",
    "content": "Metadata-Version: 1.0\nName: pyserial\nVersion: 2.6\nSummary: Python Serial Port Extension\nHome-page: http://pyserial.sourceforge.net/\nAuthor: Chris Liechti\nAuthor-email: cliechti@gmx.net\nLicense: Python\nDescription: Python Serial Port Extension for Win32, Linux, BSD, Jython, IronPython\nPlatform: any\nClassifier: Development Status :: 5 - Production/Stable\nClassifier: Intended Audience :: Developers\nClassifier: Intended Audience :: End Users/Desktop\nClassifier: License :: OSI Approved :: Python Software Foundation License\nClassifier: Natural Language :: English\nClassifier: Operating System :: POSIX\nClassifier: Operating System :: Microsoft :: Windows\nClassifier: Programming Language :: Python\nClassifier: Programming Language :: Python :: 2\nClassifier: Programming Language :: Python :: 2.3\nClassifier: Programming Language :: Python :: 2.4\nClassifier: Programming Language :: Python :: 2.5\nClassifier: Programming Language :: Python :: 2.6\nClassifier: Programming Language :: Python :: 2.7\nClassifier: Programming Language :: Python :: 3\nClassifier: Programming Language :: Python :: 3.0\nClassifier: Programming Language :: Python :: 3.1\nClassifier: Programming Language :: Python :: 3.2\nClassifier: Topic :: Communications\nClassifier: Topic :: Software Development :: Libraries\nClassifier: Topic :: Software Development :: Libraries :: Python Modules\nClassifier: Topic :: Terminals :: Serial\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/README.txt",
    "content": "==========\n pySerial\n==========\n\nOverview\n========\nThis module encapsulates the access for the serial port. It provides backends\nfor Python running on Windows, Linux, BSD (possibly any POSIX compliant\nsystem), Jython and IronPython (.NET and Mono). The module named \"serial\"\nautomatically selects the appropriate backend.\n\n- Project Homepage: http://pyserial.sourceforge.net\n- Project page on SourceForge: http://sourceforge.net/projects/pyserial/\n- SVN repository: http://sourceforge.net/svn/?group_id=46487\n- Download Page: http://sourceforge.net/project/showfiles.php?group_id=46487\n\nBSD license, (C) 2001-2011 Chris Liechti <cliechti@gmx.net>\n\n\nDocumentation\n=============\nFor API documentation, usage and examples see files in the \"documentation\"\ndirectory.  The \".rst\" files can be read in any text editor or being converted to\nHTML or PDF using Sphinx. An online HTML version is at\nhttp://pyserial.sourceforge.net.\n\n\nExamples\n========\nExamples and unit tests are in the directory \"examples\".\n\n\nInstallation\n============\nDetailed information can be found in \"documentation/pyserial.rst\".\n\nThe usual setup.py for Python libraries is used for the source distribution.\nWindows installers are also available (see download link above).\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/documentation/Makefile",
    "content": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nPAPER         =\n\n# Internal variables.\nPAPEROPT_a4     = -D latex_paper_size=a4\nPAPEROPT_letter = -D latex_paper_size=letter\nALLSPHINXOPTS   = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n\n.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest\n\nhelp:\n\t@echo \"Please use \\`make <target>' where <target> is one of\"\n\t@echo \"  html      to make standalone HTML files\"\n\t@echo \"  dirhtml   to make HTML files named index.html in directories\"\n\t@echo \"  pickle    to make pickle files\"\n\t@echo \"  json      to make JSON files\"\n\t@echo \"  htmlhelp  to make HTML files and a HTML help project\"\n\t@echo \"  qthelp    to make HTML files and a qthelp project\"\n\t@echo \"  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter\"\n\t@echo \"  changes   to make an overview of all changed/added/deprecated items\"\n\t@echo \"  linkcheck to check all external links for integrity\"\n\t@echo \"  doctest   to run all doctests embedded in the documentation (if enabled)\"\n\nclean:\n\t-rm -rf _build/*\n\nhtml:\n\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html\n\t@echo\n\t@echo \"Build finished. The HTML pages are in _build/html.\"\n\ndirhtml:\n\t$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) _build/dirhtml\n\t@echo\n\t@echo \"Build finished. The HTML pages are in _build/dirhtml.\"\n\npickle:\n\t$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle\n\t@echo\n\t@echo \"Build finished; now you can process the pickle files.\"\n\njson:\n\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json\n\t@echo\n\t@echo \"Build finished; now you can process the JSON files.\"\n\nhtmlhelp:\n\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp\n\t@echo\n\t@echo \"Build finished; now you can run HTML Help Workshop with the\" \\\n\t      \".hhp project file in _build/htmlhelp.\"\n\nqthelp:\n\t$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) _build/qthelp\n\t@echo\n\t@echo \"Build finished; now you can run \"qcollectiongenerator\" with the\" \\\n\t      \".qhcp project file in _build/qthelp, like this:\"\n\t@echo \"# qcollectiongenerator _build/qthelp/pySerial.qhcp\"\n\t@echo \"To view the help file:\"\n\t@echo \"# assistant -collectionFile _build/qthelp/pySerial.qhc\"\n\nlatex:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex\n\t@echo\n\t@echo \"Build finished; the LaTeX files are in _build/latex.\"\n\t@echo \"Run \\`make all-pdf' or \\`make all-ps' in that directory to\" \\\n\t      \"run these through (pdf)latex.\"\n\nchanges:\n\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes\n\t@echo\n\t@echo \"The overview file is in _build/changes.\"\n\nlinkcheck:\n\t$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck\n\t@echo\n\t@echo \"Link check complete; look for any errors in the above output \" \\\n\t      \"or in _build/linkcheck/output.txt.\"\n\ndoctest:\n\t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) _build/doctest\n\t@echo \"Testing of doctests in the sources finished, look at the \" \\\n\t      \"results in _build/doctest/output.txt.\"\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/documentation/appendix.rst",
    "content": "==========\n Appendix\n==========\n\nHow To\n======\n\nEnable :rfc:`2217` in programs using pySerial.\n    Patch the code where the :class:`serial.Serial` is instantiated. Replace\n    it with::\n\n        try:\n            s = serial.serial_for_url(...)\n        except AttributeError:\n            s = serial.Serial(...)\n\n    Assuming the application already stores port names as strings that's all\n    that is required. The user just needs a way to change the port setting of\n    your application to an ``rfc2217://`` :ref:`URL <URLs>` (e.g. by editing a\n    configuration file, GUI dialog etc.).\n\n    Please note that this enables all :ref:`URL <URLs>` types supported by\n    pySerial and that those involving the network are unencrypted and not\n    protected against eavesdropping.\n\nTest your setup.\n    Is the device not working as expected? Maybe it's time to check the\n    connection before proceeding. :ref:`miniterm` from the :ref:`examples`\n    can be used to open the serial port and do some basic tests.\n\n    To test cables, connecting RX to TX (loop back) and typing some characters\n    in :ref:`miniterm` is a simple test. When the characters are displayed\n    on the screen, then at least RX and TX work (they still could be swapped\n    though).\n\n\nFAQ\n===\nExample works in :ref:`miniterm` but not in script.\n    The RTS and DTR lines are switched when the port is opened. This may cause\n    some processing or reset on the connected device. In such a cases an\n    immediately following call to :meth:`write` may not be received by the\n    device.\n\n    A delay after opening the port, before the first :meth:`write`, is\n    recommended in this situation. E.g. a ``time.sleep(1)``\n\n\nApplication works when .py file is run, but fails when packaged (py2exe etc.)\n    py2exe and similar packaging programs scan the sources for import\n    statements and create a list of modules that they package. pySerial may\n    create two issues with that:\n\n    - implementations for other modules are found. On Windows, it's safe to\n      exclude 'serialposix', 'serialjava' and 'serialcli' as these are not\n      used.\n\n    - :func:`serial.serial_for_url` does a dynamic lookup of protocol handlers\n      at runtime.  If this function is used, the desired handlers have to be\n      included manually (e.g. 'serial.urlhandler.protocol_socket',\n      'serial.urlhandler.protocol_rfc2217', etc.). This can be done either with\n      the \"includes\" option in ``setup.py`` or by a dummy import in one of the\n      packaged modules.\n\nUser supplied URL handlers\n    :func:`serial.serial_for_url` can be used to access \"virtual\" serial ports\n    identified by an :ref:`URL <URLs>` scheme. E.g. for the :rfc:`2217`:\n    ``rfc2217:://``.\n\n    Custom :ref:`URL <URLs>` handlers can be added by extending the module\n    search path in :data:`serial.protocol_handler_packages`. This is possible\n    starting from pySerial V2.6.\n\n\nRelated software\n================\n\ncom0com - http://com0com.sourceforge.net/\n    Provides virtual serial ports for Windows.\n\n\nLicense\n=======\n\nCopyright (C) 2001-2011 Chris Liechti <cliechti(at)gmx.net>;\nAll Rights Reserved.\n\nThis is the Python license. In short, you can use this product in commercial\nand non-commercial applications, modify it, redistribute it.  A notification to\nthe author when you use and/or modify it is welcome.\n\n\n**TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING THIS SOFTWARE**\n\n*LICENSE AGREEMENT*\n\n1. This LICENSE AGREEMENT is between the copyright holder of this product, and\n   the Individual or Organization (\"Licensee\") accessing and otherwise using\n   this product in source or binary form and its associated documentation.\n\n2. Subject to the terms and conditions of this License Agreement, the copyright\n   holder hereby grants Licensee a nonexclusive, royalty-free, world-wide\n   license to reproduce, analyze, test, perform and/or display publicly,\n   prepare derivative works, distribute, and otherwise use this product alone\n   or in any derivative version, provided, however, that copyright holders\n   License Agreement and copyright holders notice of copyright are retained in\n   this product alone or in any derivative version prepared by Licensee.\n\n3. In the event Licensee prepares a derivative work that is based on or\n   incorporates this product or any part thereof, and wants to make the\n   derivative work available to others as provided herein, then Licensee hereby\n   agrees to include in any such work a brief summary of the changes made to\n   this product.\n\n4. The copyright holder is making this product available to Licensee on an \"AS\n   IS\" basis. THE COPYRIGHT HOLDER MAKES NO REPRESENTATIONS OR WARRANTIES,\n   EXPRESS OR IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, THE COPYRIGHT\n   HOLDER MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF\n   MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF\n   THIS PRODUCT WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.\n\n5. THE COPYRIGHT HOLDER SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF\n   THIS PRODUCT FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS\n   AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING THIS PRODUCT, OR\n   ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.\n\n6. This License Agreement will automatically terminate upon a material breach\n   of its terms and conditions.\n\n7. Nothing in this License Agreement shall be deemed to create any relationship\n   of agency, partnership, or joint venture between the copyright holder and\n   Licensee. This License Agreement does not grant permission to use trademarks\n   or trade names from the copyright holder in a trademark sense to endorse or\n   promote products or services of Licensee, or any third party.\n\n8. By copying, installing or otherwise using this product, Licensee agrees to\n   be bound by the terms and conditions of this License Agreement.\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/documentation/conf.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# pySerial documentation build configuration file, created by\n# sphinx-quickstart on Tue Jul 21 00:27:45 2009.\n#\n# This file is execfile()d with the current directory set to its containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\nimport sys, os\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#sys.path.append(os.path.abspath('.'))\n\n# -- General configuration -----------------------------------------------------\n\n# Add any Sphinx extension module names here, as strings. They can be extensions\n# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.\nextensions = ['sphinx.ext.intersphinx']\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix of source filenames.\nsource_suffix = '.rst'\n\n# The encoding of source files.\n#source_encoding = 'utf-8'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = u'pySerial'\ncopyright = u'2001-2010, Chris Liechti'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = '2.6'\n# The full version, including alpha/beta/rc tags.\nrelease = '2.6'\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#language = None\n\n# There are two options for replacing |today|: either, you set today to some\n# non-false value, then it is used:\n#today = ''\n# Else, today_fmt is used as the format for a strftime call.\n#today_fmt = '%B %d, %Y'\n\n# List of documents that shouldn't be included in the build.\n#unused_docs = []\n\n# List of directories, relative to source directory, that shouldn't be searched\n# for source files.\nexclude_trees = ['_build']\n\n# The reST default role (used for this markup: `text`) to use for all documents.\n#default_role = None\n\n# If true, '()' will be appended to :func: etc. cross-reference text.\n#add_function_parentheses = True\n\n# If true, the current module name will be prepended to all description\n# unit titles (such as .. function::).\n#add_module_names = True\n\n# If true, sectionauthor and moduleauthor directives will be shown in the\n# output. They are ignored by default.\n#show_authors = False\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# A list of ignored prefixes for module index sorting.\n#modindex_common_prefix = []\n\n\n# -- Options for HTML output ---------------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  Major themes that come with\n# Sphinx are currently 'default' and 'sphinxdoc'.\nhtml_theme = 'default'\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#html_theme_options = {}\n\n# Add any paths that contain custom themes here, relative to this directory.\n#html_theme_path = []\n\n# The name for this set of Sphinx documents.  If None, it defaults to\n# \"<project> v<release> documentation\".\n#html_title = None\n\n# A shorter title for the navigation bar.  Default is the same as html_title.\n#html_short_title = None\n\n# The name of an image file (relative to this directory) to place at the top\n# of the sidebar.\nhtml_logo = 'pyserial.png'\n\n# The name of an image file (within the static path) to use as favicon of the\n# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32\n# pixels large.\n#html_favicon = None\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['_static']\n\n# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,\n# using the given strftime format.\n#html_last_updated_fmt = '%b %d, %Y'\n\n# If true, SmartyPants will be used to convert quotes and dashes to\n# typographically correct entities.\n#html_use_smartypants = True\n\n# Custom sidebar templates, maps document names to template names.\n#html_sidebars = {}\n\n# Additional templates that should be rendered to pages, maps page names to\n# template names.\n#html_additional_pages = {}\n\n# If false, no module index is generated.\n#html_use_modindex = True\n\n# If false, no index is generated.\n#html_use_index = True\n\n# If true, the index is split into individual pages for each letter.\n#html_split_index = False\n\n# If true, links to the reST sources are added to the pages.\n#html_show_sourcelink = True\n\n# If true, an OpenSearch description file will be output, and all pages will\n# contain a <link> tag referring to it.  The value of this option must be the\n# base URL from which the finished HTML is served.\n#html_use_opensearch = ''\n\n# If nonempty, this is the file name suffix for HTML files (e.g. \".xhtml\").\n#html_file_suffix = ''\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'pySerialdoc'\n\n\n# -- Options for LaTeX output --------------------------------------------------\n\n# The paper size ('letter' or 'a4').\n#latex_paper_size = 'letter'\n\n# The font size ('10pt', '11pt' or '12pt').\n#latex_font_size = '10pt'\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title, author, documentclass [howto/manual]).\nlatex_documents = [\n  ('index', 'pySerial.tex', u'pySerial Documentation',\n   u'Chris Liechti', 'manual'),\n]\n\n# The name of an image file (relative to this directory) to place at the top of\n# the title page.\nlatex_logo = 'pyserial.png'\n\n# For \"manual\" documents, if this is true, then toplevel headings are parts,\n# not chapters.\n#latex_use_parts = False\n\n# Additional stuff for the LaTeX preamble.\n#latex_preamble = ''\n\n# Documents to append as an appendix to all manuals.\n#latex_appendices = []\n\n# If false, no module index is generated.\n#latex_use_modindex = True\n\n# for external links to standard library\nintersphinx_mapping = {\n        #~ 'python': ('http://docs.python.org', None),\n        'py': ('http://docs.python.org', None),\n        }\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/documentation/examples.rst",
    "content": ".. _examples:\n\n==========\n Examples\n==========\n\n.. _miniterm:\n\nMiniterm\n========\nThis is a console application that provides a small terminal application.\nMiniterm itself does not implement any terminal features such as VT102\ncompatibility. However it inherits these features from the terminal it is run.\nFor example on GNU/Linux running from an xterm it will support the escape\nsequences of the xterm. On Windows the typical console window is dumb and does\nnot support any escapes. When ANSI.sys is loaded it supports some escapes.\n\nMiniterm::\n\n    --- Miniterm on /dev/ttyS0: 9600,8,N,1 ---\n    --- Quit: Ctrl+]  |  Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---\n\nCommand line options can be given so that binary data including escapes for\nterminals are escaped or output as hex.\n\nMiniterm supports :rfc:`2217` remote serial ports and raw sockets using :ref:`URLs`\nsuch as ``rfc2217:://<host>:<port>`` respectively ``socket://<host>:<port>`` as\n*port* argument when invoking.\n\nCommand line options ``python -m serial.tools.miniterm -h``::\n\n    Usage: miniterm.py [options] [port [baudrate]]\n\n    Miniterm - A simple terminal program for the serial port.\n\n    Options:\n      -h, --help            show this help message and exit\n      -p PORT, --port=PORT  port, a number (default 0) or a device name\n                            (deprecated option)\n      -b BAUDRATE, --baud=BAUDRATE\n                            set baud rate, default 9600\n      --parity=PARITY       set parity, one of [N, E, O, S, M], default=N\n      -e, --echo            enable local echo (default off)\n      --rtscts              enable RTS/CTS flow control (default off)\n      --xonxoff             enable software flow control (default off)\n      --cr                  do not send CR+LF, send CR only\n      --lf                  do not send CR+LF, send LF only\n      -D, --debug           debug received data (escape non-printable chars)\n                            --debug can be given multiple times: 0: just print\n                            what is received 1: escape non-printable characters,\n                            do newlines as unusual 2: escape non-printable\n                            characters, newlines too 3: hex dump everything\n      --rts=RTS_STATE       set initial RTS line state (possible values: 0, 1)\n      --dtr=DTR_STATE       set initial DTR line state (possible values: 0, 1)\n      -q, --quiet           suppress non error messages\n      --exit-char=EXIT_CHAR\n                            ASCII code of special character that is used to exit\n                            the application\n      --menu-char=MENU_CHAR\n                            ASCII code of special character that is used to\n                            control miniterm (menu)\n\n\nMiniterm supports some control functions. Typing :kbd:`Ctrl+T Ctrl+H` when it is\nrunning shows the help text::\n\n    --- pySerial - miniterm - help\n    ---\n    --- Ctrl+]   Exit program\n    --- Ctrl+T   Menu escape key, followed by:\n    --- Menu keys:\n    ---       Ctrl+T  Send the menu character itself to remote\n    ---       Ctrl+]  Send the exit character to remote\n    ---       Ctrl+I  Show info\n    ---       Ctrl+U  Upload file (prompt will be shown)\n    --- Toggles:\n    ---       Ctrl+R  RTS          Ctrl+E  local echo\n    ---       Ctrl+D  DTR          Ctrl+B  BREAK\n    ---       Ctrl+L  line feed    Ctrl+A  Cycle repr mode\n    ---\n    --- Port settings (Ctrl+T followed by the following):\n    --- p             change port\n    --- 7 8           set data bits\n    --- n e o s m     change parity (None, Even, Odd, Space, Mark)\n    --- 1 2 3         set stop bits (1, 2, 1.5)\n    --- b             change baud rate\n    --- x X           disable/enable software flow control\n    --- r R           disable/enable hardware flow control\n\n.. versionchanged:: 2.5\n    Added :kbd:`Ctrl+T` menu and added support for opening URLs.\n.. versionchanged:: 2.6\n    File moved from the examples to :mod:`serial.tools.miniterm`.\n\nminiterm.py_\n    The miniterm program.\n\nsetup-miniterm-py2exe.py_\n    This is a py2exe setup script for Windows. It can be used to create a\n    standalone ``miniterm.exe``.\n\n.. _miniterm.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/serial/tools/miniterm.py\n.. _setup-miniterm-py2exe.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/examples/setup-miniterm-py2exe.py\n\n\nTCP/IP - serial bridge\n======================\nThis program opens a TCP/IP port. When a connection is made to that port (e.g.\nwith telnet) it forwards all data to the serial port and vice versa.\n\nThis example only exports a raw socket connection. The next example\nbelow gives the client much more control over the remote serial port.\n\n- The serial port settings are set on the command line when starting the\n  program.\n- There is no possibility to change settings from remote.\n- All data is passed through as-is.\n\n::\n\n    Usage: tcp_serial_redirect.py [options] [port [baudrate]]\n\n    Simple Serial to Network (TCP/IP) redirector.\n\n    Options:\n      -h, --help            show this help message and exit\n      -q, --quiet           suppress non error messages\n      --spy                 peek at the communication and print all data to the\n                            console\n\n      Serial Port:\n        Serial port settings\n\n        -p PORT, --port=PORT\n                            port, a number (default 0) or a device name\n        -b BAUDRATE, --baud=BAUDRATE\n                            set baud rate, default: 9600\n        --parity=PARITY     set parity, one of [N, E, O], default=N\n        --rtscts            enable RTS/CTS flow control (default off)\n        --xonxoff           enable software flow control (default off)\n        --rts=RTS_STATE     set initial RTS line state (possible values: 0, 1)\n        --dtr=DTR_STATE     set initial DTR line state (possible values: 0, 1)\n\n      Network settings:\n        Network configuration.\n\n        -P LOCAL_PORT, --localport=LOCAL_PORT\n                            local TCP port\n        --rfc2217           allow control commands with Telnet extension RFC-2217\n\n      Newline Settings:\n        Convert newlines between network and serial port. Conversion is\n        normally disabled and can be enabled by --convert.\n\n        -c, --convert       enable newline conversion (default off)\n        --net-nl=NET_NEWLINE\n                            type of newlines that are expected on the network\n                            (default: LF)\n        --ser-nl=SER_NEWLINE\n                            type of newlines that are expected on the serial port\n                            (default: CR+LF)\n\n    NOTE: no security measures are implemented. Anyone can remotely connect to\n    this service over the network.  Only one connection at once is supported. When\n    the connection is terminated it waits for the next connect.\n\n\ntcp_serial_redirect.py_\n    Main program.\n\n.. _tcp_serial_redirect.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/examples/tcp_serial_redirect.py\n\nSingle-port TCP/IP - serial bridge (RFC 2217)\n=============================================\nSimple cross platform :rfc:`2217` serial port server. It uses threads and is\nportable (runs on POSIX, Windows, etc).\n\n- The port settings and control lines (RTS/DTR) can be changed at any time\n  using :rfc:`2217` requests. The status lines (DSR/CTS/RI/CD) are polled every\n  second and notifications are sent to the client.\n- Telnet character IAC (0xff) needs to be doubled in data stream. IAC followed\n  by an other value is interpreted as Telnet command sequence.\n- Telnet negotiation commands are sent when connecting to the server.\n- RTS/DTR are activated on client connect and deactivated on disconnect.\n- Default port settings are set again when client disconnects.\n\n::\n\n    Usage: rfc2217_server.py [options] port\n\n    RFC 2217 Serial to Network (TCP/IP) redirector.\n\n    Options:\n      -h, --help            show this help message and exit\n      -p LOCAL_PORT, --localport=LOCAL_PORT\n                            local TCP port\n\n    NOTE: no security measures are implemented. Anyone can remotely connect to\n    this service over the network.  Only one connection at once is supported. When\n    the connection is terminated it waits for the next connect.\n\n.. versionadded:: 2.5\n\nrfc2217_server.py_\n    Main program.\n\nsetup-rfc2217_server-py2exe.py_\n    This is a py2exe setup script for Windows. It can be used to create a\n    standalone ``rfc2217_server.exe``.\n\n.. _rfc2217_server.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/examples/rfc2217_server.py\n.. _setup-rfc2217_server-py2exe.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/examples/setup-rfc2217_server-py2exe.py\n\n\nMulti-port TCP/IP - serial bridge (RFC 2217)\n============================================\nThis example implements a TCP/IP to serial port service that works with\nmultiple ports at once. It uses select, no threads, for the serial ports and\nthe network sockets and therefore runs on POSIX systems only.\n\n- Full control over the serial port with :rfc:`2217`.\n- Check existence of ``/tty/USB0...8``. This is done every 5 seconds using\n  ``os.path.exists``.\n- Send zeroconf announcements when port appears or disappears (uses\n  python-avahi and dbus). Service name: ``_serial_port._tcp``.\n- Each serial port becomes available as one TCP/IP server. e.g.\n  ``/dev/ttyUSB0`` is reachable at ``<host>:7000``.\n- Single process for all ports and sockets (not per port).\n- The script can be started as daemon.\n- Logging to stdout or when run as daemon to syslog.\n- Default port settings are set again when client disconnects.\n- modem status lines (CTS/DSR/RI/CD) are not polled periodically and the server\n  therefore does not send NOTIFY_MODEMSTATE on its own. However it responds to\n  request from the client (i.e. use the ``poll_modem`` option in the URL when\n  using a pySerial client.)\n\nRequirements:\n\n- Python (>= 2.4)\n- python-avahi\n- python-dbus\n- python-serial (>= 2.5)\n\nInstallation as daemon:\n\n- Copy the script ``port_publisher.py`` to ``/usr/local/bin``.\n- Copy the script ``port_publisher.sh`` to ``/etc/init.d``.\n- Add links to the runlevels using ``update-rc.d port_publisher.sh defaults 99``\n- Thats it :-) the service will be started on next reboot. Alternatively run\n  ``invoke-rc.d port_publisher.sh start`` as root.\n\n.. versionadded:: 2.5 new example\n\nport_publisher.py_\n    Multi-port TCP/IP-serial converter (RFC 2217) for POSIX environments.\n\nport_publisher.sh_\n    Example init.d script.\n\n.. _port_publisher.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/examples/port_publisher.py\n.. _port_publisher.sh: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/examples/port_publisher.sh\n\n\nwxPython examples\n=================\nA simple terminal application for wxPython and a flexible serial port\nconfiguration dialog are shown here.\n\nwxTerminal.py_\n    A simple terminal application. Note that the length of the buffer is\n    limited by wx and it may suddenly stop displaying new input.\n\nwxTerminal.wxg_\n    A wxGlade design file for the terminal application.\n\nwxSerialConfigDialog.py_\n    A flexible serial port configuration dialog.\n\nwxSerialConfigDialog.wxg_\n    The wxGlade design file for the configuration dialog.\n\nsetup-wxTerminal-py2exe.py_\n    A py2exe setup script to package the terminal application.\n\n.. _wxTerminal.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/examples/wxTerminal.py\n.. _wxTerminal.wxg: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/examples/wxTerminal.wxg\n.. _wxSerialConfigDialog.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/examples/wxSerialConfigDialog.py\n.. _wxSerialConfigDialog.wxg: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/examples/wxSerialConfigDialog.wxg\n.. _setup-wxTerminal-py2exe.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/examples/setup-wxTerminal-py2exe.py\n\n\nWrapper class\n=============\nThis example provides a subclass based on ``Serial`` that has an alternative\nimplementation of ``readline()``\n\nenhancedserial.py_\n    A class with alternative ``readline()`` implementation.\n\n.. _enhancedserial.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/examples/enhancedserial.py\n\n\nUnit tests\n==========\nThe project uses a number of unit test to verify the functionality. They all\nneed a loop back connector. The scripts itself contain more information. All\ntest scripts are contained in the directory ``test``.\n\nThe unit tests are performed on port ``0`` unless a different device name or\n``rfc2217://`` URL is given on the command line (argv[1]).\n\nrun_all_tests.py_\n    Collect all tests from all ``test*`` files and run them. By default, the\n    ``loop://`` device is used.\n\ntest.py_\n    Basic tests (binary capabilities, timeout, control lines).\n\ntest_advanced.py_\n    Test more advanced features (properties).\n\ntest_high_load.py_\n    Tests involving sending a lot of data.\n\ntest_readline.py_\n    Tests involving readline.\n\ntest_iolib.py_\n    Tests involving the :mod:`io` library. Only available for Python 2.6 and\n    newer.\n\ntest_url.py_\n    Tests involving the :ref:`URL <URLs>` feature.\n\n.. _run_all_tests.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/test/run_all_tests.py\n.. _test.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/test/test.py\n.. _test_advanced.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/test/test_advanced.py\n.. _test_high_load.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/test/test_high_load.py\n.. _test_readline.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/test/test_readline.py\n.. _test_iolib.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/test/test_iolib.py\n.. _test_url.py: http://pyserial.svn.sourceforge.net/viewvc/*checkout*/pyserial/trunk/pyserial/test/test_url.py\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/documentation/index.rst",
    "content": ".. pySerial documentation master file\n\nWelcome to pySerial's documentation\n===================================\n\nThis module encapsulates the access for the serial port. It provides backends\nfor Python running on Windows, Linux, BSD (possibly any POSIX compliant\nsystem), Jython and IronPython (.NET and Mono). The module named \"serial\"\nautomatically selects the appropriate backend.\n\nOther pages (online)\n\n- `project page on SourceForge`_\n- `SVN repository`_\n- `Download Page`_ with releases\n- This page, when viewed online, is at http://pyserial.sf.net.\n\n.. _`project page on SourceForge`: http://sourceforge.net/projects/pyserial/\n.. _`SVN repository`: http://sourceforge.net/svn/?group_id=46487\n.. _`Download Page`: http://pypi.python.org/pypi/pyserial\n\n\nContents:\n\n.. toctree::\n    :maxdepth: 2\n\n    pyserial\n    shortintro\n    examples\n    pyserial_api\n    pyparallel\n    appendix\n\nIndices and tables\n==================\n\n* :ref:`genindex`\n* :ref:`modindex`\n* :ref:`search`\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/documentation/pyparallel.rst",
    "content": "============\n pyParallel\n============\n\n.. note:: This module is in development (since years ;-)\n\nOverview\n========\nThis module encapsulates the access for the parallel port. It provides backends\nfor Python running on Windows and Linux. Other platforms are possible too but\nnot yet integrated.\n\nThis module is still under development. But it may be useful for developers.\n\nCopyright (C) 2001-2003 Chris Liechti <cliechti(at)gmx.net>\n\nHere is the `project page on SourceForge`_ and here is the `SVN repository`_.\n\n.. _`project page on SourceForge`: http://sourceforge.net/projects/pyserial/\n.. _`SVN repository`: http://sourceforge.net/svn/?group_id=46487\n\n\nFeatures\n--------\n* same class based interface on all supported platforms\n* port numbering starts at zero, no need to know the port name in the user program\n* port string (device name) can be specified if access through numbering is inappropriate\n\n\nRequirements\n------------\n* Python 2.2 or newer\n* \"Java Communications\" (JavaComm) extension for Java/Jython\n\n\nInstallation\n------------\nExtract files from the archive, open a shell/console in that directory and let\nDistutils do the rest: ``python setup.py install``\n\nThe files get installed in the \"Lib/site-packages\" directory in newer Python versions.\n\nThe windows version needs a compiled extension and the giveio.sys driver for\nWindows NT/2k/XP. The extension module can be compiled with Distutils with\neither MSVC or GCC/mingw32.\n\nIt is released under a free software license, see LICENSE.txt for more details.\n\n\nShort introduction\n==================\n::\n\n    >>> import parallel\n    >>> p = parallel.Parallel()     # open LPT1\n    >>> p.setData(0x55)\n\n\nExamples\n--------\nPlease look in the SVN Repository. There is an example directory where you can\nfind a simple terminal and more.\nhttp://pyserial.svn.sourceforge.net/viewvc/pyserial/trunk/pyparallel/examples/\n\n\nAPI\n===\n\n.. module:: parallel\n\n.. class:: Parallel\n\n    .. method:: __init__(port)\n\n        Open given parallel port.\n\n    .. method:: setData(value)\n\n        Apply the given byte to the data pins of the parallel port.\n\n    .. method:: setDataStrobe(level)\n\n        Set the \"data strobe\" line to the given state.\n\n    .. method:: setAutoFeed(level)\n\n        Set \"auto feed\" line to given state.\n\n    .. method:: setInitOut(level)\n\n        Set \"initialize\" line to given state.\n\n    .. method: setSelect(level)\n\n        Set \"select\" line to given state.\n\n    .. method:getInError()\n\n        Set \"Error\" line to given state.\n\n    .. method:: getInSelected()\n\n        Read level of \"select\" line.\n\n    .. method:: getInPaperOut()\n\n        Read level of \"paper out\" line.\n\n    .. method:: getInAcknowledge()\n\n        Read level of \"Acknowledge\" line.\n\n    .. method: getInBusy()\n\n        Read level of \"busy\" line.\n\n\n.. module:: parallel.parallelutil\n\n.. class:: BitaccessMeta\n\n    This mix-in class adds a few properties that allow easier bit access to the\n    data lines. (D0 .. D7) e.g. p.D0 refers to the first bit of the data\n    lines.\n\n.. class:: VirtualParallelPort\n\n    This class provides a virtual parallel port implementation, useful\n    for tests and simulations without real hardware.\n\n\nNotes\n=====\n\nLinux\n-----\n1. The :manpage:`lp(4)` module must be unloaded, ``rmmod lp``. ``lp`` claims\n   exclusive access to the port and other programs won't be able to use it.\n\n2. The :manpage:`ppdev(4)` module needs to be loaded, ``modprobe ppdev``. When\n   ``udev`` is in use, (default with 2.6 kernels) this will create a\n   ``/dev/parport0``.\n\n3. The user needs to have write permissions to ``/dev/parport0``. Many\n   distributions have an ``lp`` group that owns the device; the simplest is to\n   add the user account to this group. Simply changing permissions on the\n   device is not the best strategy as they will be reverted to their defaults\n   next time the driver is loaded.\n\n\nWindows\n-------\nThe giveio driver must be installed as the module needs direct access to the\nhardware. This also means that USB parallel port adapters won't be supported.\n\n\nMisc\n====\nReferences\n----------\n* Python: http://www.python.org/\n* Jython: http://www.jython.org/\n* Java@IBM: http://www-106.ibm.com/developerworks/java/jdk/ (JavaComm links are\n  on the download page for the respective platform JDK)\n* Java@SUN: http://java.sun.com/products/\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/documentation/pyserial.rst",
    "content": "==========\n pySerial\n==========\n\nOverview\n========\nThis module encapsulates the access for the serial port. It provides backends\nfor Python running on Windows, Linux, BSD (possibly any POSIX compliant\nsystem), Jython and IronPython (.NET and Mono). The module named \"serial\"\nautomatically selects the appropriate backend.\n\nIt is released under a free software license, see LICENSE_ for more\ndetails.\n\nCopyright (C) 2001-2010 Chris Liechti <cliechti(at)gmx.net>\n\nOther pages (online)\n\n- `project page on SourceForge`_\n- `SVN repository`_\n- `Download Page`_ with releases\n- This page, when viewed online is at http://pyserial.sf.net.\n\n.. _LICENSE: appendix.html#license\n.. _`project page on SourceForge`: http://sourceforge.net/projects/pyserial/\n.. _`SVN repository`: http://sourceforge.net/svn/?group_id=46487\n.. _`Download Page`: http://sourceforge.net/project/showfiles.php?group_id=46487\n\n\nFeatures\n========\n- Same class based interface on all supported platforms.\n- Access to the port settings through Python properties.\n- Support for different byte sizes, stop bits, parity and flow control with\n  RTS/CTS and/or Xon/Xoff.\n- Working with or without receive timeout.\n- File like API with \"read\" and \"write\" (\"readline\" etc. also supported).\n- The files in this package are 100% pure Python.\n- The port is set up for binary transmission. No NULL byte stripping, CR-LF\n  translation etc. (which are many times enabled for POSIX.) This makes this\n  module universally useful.\n- Compatible with :mod:`io` library (Python 2.6+)\n- RFC 2217 client (experimental), server provided in the examples.\n\n\nRequirements\n============\n- Python 2.3 or newer, including Python 3.x\n- ctypes extensions on Windows (is in standard library since Python 2.5+)\n- \"Java Communications\" (JavaComm) or compatible extension for Java/Jython\n\n\nInstallation\n============\n\npyserial\n--------\nThis installs a package that can be used from Python (``import serial``).\n\nTo install the module for all users on the system, administrator rights (root)\nis required..\n\nFrom source (tar.gz or checkout)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nDownload the archive from http://pypi.python.org/pypi/pyserial.\nUnpack the archive, enter the ``pyserial-x.y`` directory and run::\n\n    python setup.py install\n\nFor Python 3.x::\n\n    python3 setup.py install\n\nFrom PyPI\n~~~~~~~~~\nAlternatively it can be installed from PyPI, either manually downloading the\nfiles and installing as described above or using::\n\n    pip pyserial\n\nor::\n\n    easy_install -U pyserial\n\nPackages\n~~~~~~~~\nThere are also packaged versions for some Linux distributions and Windows:\n\nDebian/Ubuntu\n    A package is available under the name \"python-serial\". Note that some\n    distributions package an older version of pySerial.\n\nWindows\n    There is also a Windows installer for end users. It is located in the\n    PyPi_.  Developers may be interested to get the source archive, because it\n    contains examples and the readme.\n\n.. _PyPi: http://pypi.python.org/pypi/pyserial\n\n\nReferences\n==========\n* Python: http://www.python.org/\n* Jython: http://www.jython.org/\n* Java@IBM: http://www-106.ibm.com/developerworks/java/jdk/ (JavaComm links are\n  on the download page for the respective platform JDK)\n* Java@SUN: http://java.sun.com/products/\n* IronPython: http://www.codeplex.com/IronPython\n* setuptools: http://peak.telecommunity.com/DevCenter/setuptools\n\n\nOlder Versions\n==============\nOlder versions are still available on the `Download Page`_. pySerial 1.21 is\ncompatible with Python 2.0 on Windows, Linux and several un*x like systems,\nMacOSX and Jython.\n\nOn windows releases older than 2.5 will depend on pywin32_ (previously known as\nwin32all)\n\n.. _`Download Page`: http://sourceforge.net/project/showfiles.php?group_id=46487\n.. _pywin32: http://pypi.python.org/pypi/pywin32\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/documentation/pyserial_api.rst",
    "content": "==============\n pySerial API\n==============\n\n.. module:: serial\n\nClasses\n=======\n\nNative ports\n------------\n\n.. class:: Serial\n\n    .. method:: __init__(port=None, baudrate=9600, bytesize=EIGHTBITS, parity=PARITY_NONE, stopbits=STOPBITS_ONE, timeout=None, xonxoff=False, rtscts=False, writeTimeout=None, dsrdtr=False, interCharTimeout=None)\n\n        :param port:\n            Device name or port number number or :const:`None`.\n\n        :param baudrate:\n            Baud rate such as 9600 or 115200 etc.\n\n        :param bytesize:\n            Number of data bits. Possible values:\n            :const:`FIVEBITS`, :const:`SIXBITS`, :const:`SEVENBITS`,\n            :const:`EIGHTBITS`\n\n        :param parity:\n            Enable parity checking. Possible values:\n            :const:`PARITY_NONE`, :const:`PARITY_EVEN`, :const:`PARITY_ODD`\n            :const:`PARITY_MARK`, :const:`PARITY_SPACE`\n\n        :param stopbits:\n            Number of stop bits. Possible values:\n            :const:`STOPBITS_ONE`, :const:`STOPBITS_ONE_POINT_FIVE`,\n            :const:`STOPBITS_TWO`\n\n        :param timeout:\n            Set a read timeout value.\n\n        :param xonxoff:\n            Enable software flow control.\n\n        :param rtscts:\n            Enable hardware (RTS/CTS) flow control.\n\n        :param dsrdtr:\n            Enable hardware (DSR/DTR) flow control.\n\n        :param writeTimeout:\n            Set a write timeout value.\n\n        :param interCharTimeout:\n            Inter-character timeout, :const:`None` to disable (default).\n\n        :exception ValueError:\n            Will be raised when parameter are out of range, e.g. baud rate, data bits.\n\n        :exception SerialException:\n            In case the device can not be found or can not be configured.\n\n\n        The port is immediately opened on object creation, when a *port* is\n        given. It is not opened when *port* is :const:`None` and a successive call\n        to :meth:`open` will be needed.\n\n        Possible values for the parameter *port*:\n\n        - Number: number of device, numbering starts at zero.\n        - Device name: depending on operating system. e.g. ``/dev/ttyUSB0``\n          on GNU/Linux or ``COM3`` on Windows.\n\n        The parameter *baudrate* can be one of the standard values:\n        50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,\n        9600, 19200, 38400, 57600, 115200.\n        These are well supported on all platforms. Standard values above 115200\n        such as: 230400, 460800, 500000, 576000, 921600, 1000000, 1152000,\n        1500000, 2000000, 2500000, 3000000, 3500000, 4000000 also work on many\n        platforms.\n\n        Non-standard values are also supported on some platforms (GNU/Linux, MAC\n        OSX >= Tiger, Windows). Though, even on these platforms some serial\n        ports may reject non-standard values.\n\n        Possible values for the parameter *timeout*:\n\n        - ``timeout = None``:  wait forever\n        - ``timeout = 0``:     non-blocking mode (return immediately on read)\n        - ``timeout = x``:     set timeout to ``x`` seconds (float allowed)\n\n        Writes are blocking by default, unless *writeTimeout* is set. For\n        possible values refer to the list for *timeout* above.\n\n        Note that enabling both flow control methods (*xonxoff* and *rtscts*)\n        together may not be supported. It is common to use one of the methods\n        at once, not both.\n\n        *dsrdtr* is not supported by all platforms (silently ignored). Setting\n        it to ``None`` has the effect that its state follows *rtscts*.\n\n        Also consider using the function :func:`serial_for_url` instead of\n        creating Serial instances directly.\n\n        .. versionchanged:: 2.5\n            *dsrdtr* now defaults to ``False`` (instead of *None*)\n\n    .. method:: open()\n\n        Open port.\n\n    .. method:: close()\n\n        Close port immediately.\n\n    .. method:: __del__()\n\n        Destructor, close port when serial port instance is freed.\n\n\n    The following methods may raise :exc:`ValueError` when applied to a closed\n    port.\n\n    .. method:: read(size=1)\n\n        :param size: Number of bytes to read.\n        :return: Bytes read from the port.\n\n        Read *size* bytes from the serial port. If a timeout is set it may\n        return less characters as requested. With no timeout it will block\n        until the requested number of bytes is read.\n\n        .. versionchanged:: 2.5\n            Returns an instance of :class:`bytes` when available (Python 2.6\n            and newer) and :class:`str` otherwise.\n\n    .. method:: write(data)\n\n        :param data: Data to send.\n        :return: Number of bytes written.\n        :exception SerialTimeoutException:\n            In case a write timeout is configured for the port and the time is\n            exceeded.\n\n        Write the string *data* to the port.\n\n        .. versionchanged:: 2.5\n            Accepts instances of :class:`bytes` and :class:`bytearray` when\n            available (Python 2.6 and newer) and :class:`str` otherwise.\n\n        .. versionchanged:: 2.5\n            Write returned ``None`` in previous versions.\n\n    .. method:: inWaiting()\n\n        Return the number of chars in the receive buffer.\n\n    .. method:: flush()\n\n        Flush of file like objects. In this case, wait until all data is\n        written.\n\n    .. method:: flushInput()\n\n        Flush input buffer, discarding all it's contents.\n\n    .. method:: flushOutput()\n\n        Clear output buffer, aborting the current output and\n        discarding all that is in the buffer.\n\n    .. method:: sendBreak(duration=0.25)\n\n        :param duration: Time (float) to activate the BREAK condition.\n\n        Send break condition. Timed, returns to idle state after given\n        duration.\n\n    .. method:: setBreak(level=True)\n\n        :param level: when true activate BREAK condition, else disable.\n\n        Set break: Controls TXD. When active, no transmitting is possible.\n\n    .. method:: setRTS(level=True)\n\n        :param level: Set control line to logic level.\n\n        Set RTS line to specified logic level.\n\n    .. method:: setDTR(level=True)\n\n        :param level: Set control line to logic level.\n\n        Set DTR line to specified logic level.\n\n    .. method:: getCTS()\n\n        :return: Current state (boolean)\n\n        Return the state of the CTS line.\n\n    .. method:: getDSR()\n\n        :return: Current state (boolean)\n\n        Return the state of the DSR line.\n\n    .. method:: getRI()\n\n        :return: Current state (boolean)\n\n        Return the state of the RI line.\n\n    .. method:: getCD()\n\n        :return: Current state (boolean)\n\n        Return the state of the CD line\n\n    Read-only attributes:\n\n    .. attribute:: name\n\n        Device name. This is always the device name even if the\n        port was opened by a number. (Read Only).\n\n        .. versionadded:: 2.5\n\n    .. attribute:: portstr\n\n        :deprecated: use :attr:`name` instead\n\n    New values can be assigned to the following attributes (properties), the\n    port will be reconfigured, even if it's opened at that time:\n\n\n    .. attribute:: port\n\n        Read or write port. When the port is already open, it will be closed\n        and reopened with the new setting.\n\n    .. attribute:: baudrate\n\n        Read or write current baud rate setting.\n\n    .. attribute:: bytesize\n\n        Read or write current data byte size setting.\n\n    .. attribute:: parity\n\n        Read or write current parity setting.\n\n    .. attribute:: stopbits\n\n        Read or write current stop bit width setting.\n\n    .. attribute:: timeout\n\n        Read or write current read timeout setting.\n\n    .. attribute:: writeTimeout\n\n        Read or write current write timeout setting.\n\n    .. attribute:: xonxoff\n\n        Read or write current software flow control rate setting.\n\n    .. attribute:: rtscts\n\n        Read or write current hardware flow control setting.\n\n    .. attribute:: dsrdtr\n\n        Read or write current hardware flow control setting.\n\n    .. attribute:: interCharTimeout\n\n        Read or write current inter character timeout setting.\n\n    The following constants are also provided:\n\n    .. attribute:: BAUDRATES\n\n        A list of valid baud rates. The list may be incomplete such that higher\n        baud rates may be supported by the device and that values in between the\n        standard baud rates are supported. (Read Only).\n\n    .. attribute:: BYTESIZES\n\n        A list of valid byte sizes for the device (Read Only).\n\n    .. attribute:: PARITIES\n\n        A list of valid parities for the device (Read Only).\n\n    .. attribute:: STOPBITS\n\n        A list of valid stop bit widths for the device (Read Only).\n\n\n    The following methods are for compatibility with the :mod:`io` library.\n\n    .. method:: readable()\n\n        :return: True\n\n        .. versionadded:: 2.5\n\n    .. method:: writable()\n\n        :return: True\n\n        .. versionadded:: 2.5\n\n    .. method:: seekable()\n\n        :return: False\n\n        .. versionadded:: 2.5\n\n    .. method:: readinto(b)\n\n        :param b: bytearray or array instance\n        :return: Number of byte read\n\n        Read up to len(b) bytes into :class:`bytearray` *b* and return the\n        number of bytes read.\n\n        .. versionadded:: 2.5\n\n    The port settings can be read and written as dictionary.\n\n    .. method:: getSettingsDict()\n\n        :return: a dictionary with current port settings.\n\n        Get a dictionary with port settings. This is useful to backup the\n        current settings so that a later point in time they can be restored\n        using :meth:`applySettingsDict`.\n\n        Note that control lines (RTS/DTR) are part of the settings.\n\n        .. versionadded:: 2.5\n\n    .. method:: applySettingsDict(d)\n\n        :param d: a dictionary with port settings.\n\n        Applies a dictionary that was created by :meth:`getSettingsDict`. Only\n        changes are applied and when a key is missing it means that the setting\n        stays unchanged.\n\n        Note that control lines (RTS/DTR) are not changed.\n\n        .. versionadded:: 2.5\n\n    Platform specific methods.\n\n    .. warning:: Programs using the following methods are not portable to other platforms!\n\n    .. method:: nonblocking()\n\n        :platform: Unix\n\n        Configure the device for nonblocking operation. This can be useful if\n        the port is used with :mod:`select`.\n\n    .. method:: fileno()\n\n        :platform: Unix\n        :return: File descriptor.\n\n        Return file descriptor number for the port that is opened by this object.\n        It is useful when serial ports are used with :mod:`select`.\n\n    .. method:: setXON(level=True)\n\n        :platform: Windows\n        :param level: Set flow control state.\n\n        Set software flow control state.\n\n.. note::\n\n    For systems that provide the :py:mod:`io` library (Python 2.6 and newer), the\n    class :class:`Serial` will derive from :py:class:`io.RawIOBase`. For all\n    others from :class:`FileLike`.\n\nImplementation detail: some attributes and functions are provided by the\nclass :class:`SerialBase` and some by the platform specific class and\nothers by the base class mentioned above.\n\n.. class:: FileLike\n\n    An abstract file like class. It is used as base class for :class:`Serial`\n    when no :py:mod:`io` module is available.\n\n    This class implements :meth:`readline` and :meth:`readlines` based on\n    :meth:`read` and :meth:`writelines` based on :meth:`write`.\n\n    Note that when the serial port was opened with no timeout, that\n    :meth:`readline` blocks until it sees a newline (or the specified size is\n    reached) and that :meth:`readlines` would never return and therefore\n    refuses to work (it raises an exception in this case)!\n\n    .. method:: writelines(sequence)\n\n        Write a list of strings to the port.\n\n\n    The following three methods are overridden in :class:`Serial`.\n\n    .. method:: flush()\n\n        Flush of file like objects. It's a no-op in this class, may be overridden.\n\n    .. method:: read()\n\n        Raises NotImplementedError, needs to be overridden by subclass.\n\n    .. method:: write(data)\n\n        Raises NotImplementedError, needs to be overridden by subclass.\n\n    The following functions are implemented for compatibility with other\n    file-like objects, however serial ports are not seekable.\n\n\n    .. method:: seek(pos, whence=0)\n\n        :exception IOError: always, as method is not supported on serial port\n\n        .. versionadded:: 2.5\n\n    .. method:: tell()\n\n        :exception IOError: always, as method is not supported on serial port\n\n        .. versionadded:: 2.5\n\n    .. method:: truncate(self, n=None)\n\n        :exception IOError: always, as method is not supported on serial port\n\n        .. versionadded:: 2.5\n\n    .. method:: isatty()\n\n        :exception IOError: always, as method is not supported on serial port\n\n        .. versionadded:: 2.5\n\n    To be able to use the file like object as iterator for e.g.\n    ``for line in Serial(0): ...`` usage:\n\n    .. method:: next()\n\n        Return the next line by calling :meth:`readline`.\n\n    .. method:: __iter__()\n\n        Returns self.\n\n    Other high level access functions.\n\n    .. method:: readline(size=None, eol='\\\\n')\n\n        :param size: Max number of bytes to read, ``None`` -> no limit.\n        :param eol: The end of line character.\n\n        Read a line which is terminated with end-of-line (*eol*) character\n        (``\\n`` by default) or until timeout.\n\n    .. method:: readlines(sizehint=None, eol='\\\\n')\n\n        :param sizehint: Ignored parameter.\n        :param eol: The end of line character.\n\n        Read a list of lines, until timeout. *sizehint* is ignored and only\n        present for API compatibility with built-in File objects.\n\n        Note that this function only returns on a timeout.\n\n    .. method:: xreadlines(sizehint=None)\n\n        Read lines, implemented as generator. Unlike *readlines* (that only\n        returns on a timeout) is this function yielding lines as they are\n        received.\n\n        .. deprecated:: 2.5\n            Use ``for line in Serial(...): ...`` instead. This method is not\n            available in Python 2.6 and newer where the :mod:`io` library is\n            available and pySerial bases on it.\n\n        .. versionchanged:: 2.5\n            Implement as generator.\n\n\n:rfc:`2217` Network ports\n-------------------------\n\n.. warning:: This implementation is currently in an experimental state. Use\n    at your own risk.\n\n.. class:: rfc2217.Serial\n\n    This implements a :rfc:`2217` compatible client. Port names are URLs_ in the\n    form: ``rfc2217://<host>:<port>[/<option>[/<option>]]``\n\n    This class API is compatible to :class:`Serial` with a few exceptions:\n\n    - numbers as port name are not allowed, only URLs in the form described\n      above.\n    - writeTimeout is not implemented\n    - The current implementation starts a thread that keeps reading from the\n      (internal) socket. The thread is managed automatically by the\n      :class:`rfc2217.Serial` port object on :meth:`open`/:meth:`close`.\n      However it may be a problem for user applications that like to use select\n      instead of threads.\n\n    Due to the nature of the network and protocol involved there are a few\n    extra points to keep in mind:\n\n    - All operations have an additional latency time.\n    - Setting control lines (RTS/CTS) needs more time.\n    - Reading the status lines (DSR/DTR etc.) returns a cached value. When that\n      cache is updated depends entirely on the server. The server itself may\n      implement a polling at a certain rate and quick changes may be invisible.\n    - The network layer also has buffers. This means that :meth:`flush`,\n      :meth:`flushInput` and :meth:`flushOutput` may work with additional delay.\n      Likewise :meth:`inWaiting` returns the size of the data arrived at the\n      object internal buffer and excludes any bytes in the network buffers or\n      any server side buffer.\n    - Closing and immediately reopening the same port may fail due to time\n      needed by the server to get ready again.\n\n    Not implemented yet / Possible problems with the implementation:\n\n    - :rfc:`2217` flow control between client and server (objects internal\n      buffer may eat all your memory when never read).\n    - No authentication support (servers may not prompt for a password etc.)\n    - No encryption.\n\n    Due to lack of authentication and encryption it is not suitable to use this\n    client for connections across the internet and should only be used in\n    controlled environments.\n\n    .. versionadded:: 2.5\n\n\n.. class:: rfc2217.PortManager\n\n    This class provides helper functions for implementing :rfc:`2217`\n    compatible servers.\n\n    Basically, it implements every thing needed for the :rfc:`2217` protocol.\n    It just does not open sockets and read/write to serial ports (though it\n    changes other port settings). The user of this class must take care of the\n    data transmission itself. The reason for that is, that this way, this class\n    supports all programming models such as threads and select.\n\n    Usage examples can be found in the examples where two TCP/IP - serial\n    converters are shown, one using threads (the single port server) and an\n    other using select (the multi port server).\n\n    .. note:: Each new client connection must create a new instance as this\n              object (and the :rfc:`2217` protocol) has internal state.\n\n    .. method:: __init__(serial_port, connection, debug_output=False)\n\n        :param serial_port: a :class:`Serial` instance that is managed.\n        :param connection: an object implementing :meth:`write`, used to write\n            to the network.\n        :param debug_output: enables debug messages: a :class:`logging.Logger`\n            instance or None.\n\n        Initializes the Manager and starts negotiating with client in Telnet\n        and :rfc:`2217` protocol. The negotiation starts immediately so that\n        the class should be instantiated in the moment the client connects.\n\n        The *serial_port* can be controlled by :rfc:`2217` commands. This\n        object will modify the port settings (baud rate etc.) and control lines\n        (RTS/DTR) send BREAK etc. when the corresponding commands are found by\n        the :meth:`filter` method.\n\n        The *connection* object must implement a :meth:`write(data)` function.\n        This function must ensure that *data* is written at once (no user data\n        mixed in, i.e. it must be thread-safe). All data must be sent in its\n        raw form (:meth:`escape` must not be used) as it is used to send Telnet\n        and :rfc:`2217` control commands.\n\n        For diagnostics of the connection or the implementation, *debug_output*\n        can be set to an instance of a :class:`logging.Logger` (e.g.\n        ``logging.getLogger('rfc2217.server')``). The caller should configure\n        the logger using ``setLevel`` for the desired detail level of the logs.\n\n    .. method:: escape(data)\n\n        :param data: data to be sent over the network.\n        :return: data, escaped for Telnet/:rfc:`2217`\n\n        A generator that escapes all data to be compatible with :rfc:`2217`.\n        Implementors of servers should use this function to process all data\n        sent over the network.\n\n        The function returns a generator which can be used in ``for`` loops.\n        It can be converted to bytes using :func:`serial.to_bytes`.\n\n    .. method:: filter(data)\n\n        :param data: data read from the network, including Telnet and\n            :rfc:`2217` controls.\n        :return: data, free from Telnet and :rfc:`2217` controls.\n\n        A generator that filters and processes all data related to :rfc:`2217`.\n        Implementors of servers should use this function to process all data\n        received from the network.\n\n        The function returns a generator which can be used in ``for`` loops.\n        It can be converted to bytes using :func:`serial.to_bytes`.\n\n    .. method:: check_modem_lines(force_notification=False)\n\n        :param force_notification: Set to false. Parameter is for internal use.\n\n        This function needs to be called periodically (e.g. every second) when\n        the server wants to send NOTIFY_MODEMSTATE messages. This is required\n        to support the client for reading CTS/DSR/RI/CD status lines.\n\n        The function reads the status line and issues the notifications\n        automatically.\n\n    .. versionadded:: 2.5\n\n.. seealso::\n\n   :rfc:`2217` - Telnet Com Port Control Option\n\n\nExceptions\n==========\n\n.. exception:: SerialException\n\n    Base class for serial port exceptions.\n\n    .. versionchanged:: 2.5\n        Now derrives from :exc:`IOError` instead of :exc:`Exception`\n\n.. exception:: SerialTimeoutException\n\n    Exception that is raised on write timeouts.\n\n\nConstants\n=========\n\n*Parity*\n\n.. data:: PARITY_NONE\n.. data:: PARITY_EVEN\n.. data:: PARITY_ODD\n.. data:: PARITY_MARK\n.. data:: PARITY_SPACE\n\n*Stop bits*\n\n.. data:: STOPBITS_ONE\n.. data:: STOPBITS_ONE_POINT_FIVE\n.. data:: STOPBITS_TWO\n\nNote that 1.5 stop bits are not supported on POSIX. It will fall back to 2 stop\nbits.\n\n*Byte size*\n\n.. data:: FIVEBITS\n.. data:: SIXBITS\n.. data:: SEVENBITS\n.. data:: EIGHTBITS\n\n\n*Others*\n\nDefault control characters (instances of :class:`bytes` for Python 3.0+) for\nsoftware flow control:\n\n.. data:: XON\n.. data:: XOFF\n\nModule version:\n\n.. data:: VERSION\n\n    A string indicating the pySerial version, such as ``2.5``.\n\n    .. versionadded:: 2.3\n\n\nModule functions and attributes\n===============================\n\n.. function:: device(number)\n\n    :param number: Port number.\n    :return: String containing device name.\n    :deprecated: Use device names directly.\n\n    Convert a port number to a platform dependent device name. Unfortunately\n    this does not work well for all platforms; e.g. some may miss USB-Serial\n    converters and enumerate only internal serial ports.\n\n    The conversion may be made off-line, that is, there is no guarantee that\n    the returned device name really exists on the system.\n\n\n.. function:: serial_for_url(url, \\*args, \\*\\*kwargs)\n\n    :param url: Device name, number or :ref:`URL <URLs>`\n    :param do_not_open: When set to true, the serial port is not opened.\n    :return: an instance of :class:`Serial` or a compatible object.\n\n    Get a native or a :rfc:`2217` implementation of the Serial class, depending\n    on port/url. This factory function is useful when an application wants\n    to support both, local ports and remote ports. There is also support\n    for other types, see :ref:`URL <URLs>` section below.\n\n    The port is not opened when a keyword parameter called *do_not_open* is\n    given and true, by default it is opened.\n\n    .. versionadded:: 2.5\n\n\n.. attribute:: protocol_handler_packages\n\n    This attribute is a list of package names (strings) that is searched for\n    protocol handlers.\n\n    e.g. we want to support a URL ``foobar://``. A module\n    ``my_handlers.protocol_foobar`` is provided by the user::\n\n        serial.protocol_handler_packages.append(\"my_handlers\")\n        s = serial.serial_for_url(\"foobar://\")\n\n    For an URL starting with ``XY://`` is the function :func:`serial_for_url`\n    attempts to import ``PACKAGE.protocol_XY`` with each candidate for\n    ``PACKAGE`` from this list.\n\n    .. versionadded:: 2.6\n\n\n.. function:: to_bytes(sequence)\n\n    :param sequence: String or list of integers\n    :returns: an instance of ``bytes``\n\n    Convert a sequence to a ``bytes`` type. This is used to write code that is\n    compatible to Python 2.x and 3.x.\n\n    In Python versions prior 3.x, ``bytes`` is a subclass of str. They convert\n    ``str([17])`` to ``'[17]'`` instead of ``'\\x11'`` so a simple\n    ``bytes(sequence)`` doesn't work for all versions of Python.\n\n    This function is used internally and in the unit tests.\n\n    .. versionadded:: 2.5\n\n\n.. _URLs:\n\nURLs\n----\nThe function :func:`serial_for_url` accepts the following types of URLs:\n\n- ``rfc2217://<host>:<port>[/<option>[/<option>]]``\n- ``socket://<host>:<port>[/<option>[/<option>]]``\n- ``loop://[<option>[/<option>]]``\n\nDevice names are also supported, e.g.:\n\n- ``/dev/ttyUSB0`` (Linux)\n- ``COM3`` (Windows)\n\nFuture releases of pySerial might add more types. Since pySerial 2.6 it is also\npossible for the user to add protocol handlers using\n:attr:`protocol_handler_packages`.\n\n``rfc2217://``\n    Used to connect to :rfc:`2217` compatible servers. All serial port\n    functions are supported. Implemented by :class:`rfc2217.Serial`.\n\n    Supported options in the URL are:\n\n    - ``ign_set_control`` does not wait for acknowledges to SET_CONTROL. This\n      option can be used for non compliant servers (i.e. when getting an\n      ``remote rejected value for option 'control'`` error when connecting).\n\n    - ``poll_modem``: The client issues NOTIFY_MODEMSTATE requests when status\n      lines are read (CTS/DTR/RI/CD). Without this option it relies on the server\n      sending the notifications automatically (that's what the RFC suggests and\n      most servers do). Enable this option when :meth:`getCTS` does not work as\n      expected, i.e. for servers that do not send notifications.\n\n    - ``timeout=<value>``: Change network timeout (default 3 seconds). This is\n      useful when the server takes a little more time to send its answers. The\n      timeout applies to the initial Telnet / :rfc:`2271` negotiation as well\n      as changing port settings or control line change commands.\n\n    - ``logging=[debug|info|warning|error]``: Prints diagnostic messages (not\n      useful for end users). It uses the logging module and a logger called\n      ``pySerial.rfc2217`` so that the application can setup up logging\n      handlers etc. It will call :meth:`logging.basicConfig` which initializes\n      for output on ``sys.stderr`` (if no logging was set up already).\n\n``socket://``\n    The purpose of this connection type is that applications using pySerial can\n    connect to TCP/IP to serial port converters that do not support :rfc:`2217`.\n\n    Uses a TCP/IP socket. All serial port settings, control and status lines\n    are ignored. Only data is transmitted and received.\n\n    Supported options in the URL are:\n\n    - ``logging=[debug|info|warning|error]``: Prints diagnostic messages (not\n      useful for end users). It uses the logging module and a logger called\n      ``pySerial.socket`` so that the application can setup up logging handlers\n      etc. It will call :meth:`logging.basicConfig` which initializes for\n      output on ``sys.stderr`` (if no logging was set up already).\n\n``loop://``\n    The least useful type. It simulates a loop back connection\n    (``RX<->TX``  ``RTS<->CTS``  ``DTR<->DSR``). It could be used to test\n    applications or run the unit tests.\n\n    Supported options in the URL are:\n\n    - ``logging=[debug|info|warning|error]``: Prints diagnostic messages (not\n      useful for end users). It uses the logging module and a logger called\n      ``pySerial.loop`` so that the application can setup up logging handlers\n      etc. It will call :meth:`logging.basicConfig` which initializes for\n      output on ``sys.stderr`` (if no logging was set up already).\n\n\nExamples:\n\n- ``rfc2217://localhost:7000``\n- ``rfc2217://localhost:7000/poll_modem``\n- ``rfc2217://localhost:7000/ign_set_control/timeout=5.5``\n- ``socket://localhost:7777``\n- ``loop://logging=debug``\n\nTools\n=====\n\n\nserial.tools.list_ports\n-----------------------\n.. module:: serial.tools.list_ports\n.. versionadded:: 2.6\n\nThis module can be executed to get a list of ports (``python -m\nserial.tools.list_ports``). It also contains the following functions.\n\n\n.. function:: comports()\n\n    :return: an iterable.\n\n    The function returns an iterable that yields tuples of three strings:\n\n    - port name as it can be passed to :class:`serial.Serial` or\n      :func:`serial.serial_for_url`\n    - description in human readable form\n    - sort of hardware ID. E.g. may contain VID:PID of USB-serial adapters.\n\n    Items are returned in no particular order. It may make sense to sort the\n    items. Also note that the reported strings are different across platforms\n    and operating systems, even for the same device.\n\n    .. note:: Support is limited to a number of operating systems. On some\n              systems description and hardware ID will not be available\n              (``None``).\n\n    :platform: Posix (/dev files)\n    :platform: Linux (/dev files, sysfs and lsusb)\n    :platform: Windows (setupapi, registry)\n\n\n.. function:: grep(regexp)\n\n    :param regexp: regular expression (see stdlib :mod:`re`)\n    :return: filtered sequence, see :func:`comports`.\n\n    Search for ports using a regular expression. Port name, description and\n    hardware ID are searched (case insensitive). The function returns an\n    iterable that contains the same tuples that :func:`comport` generates but\n    only those that match the regexp.\n\n\nserial.tools.miniterm\n-----------------------\n.. module:: serial.tools.miniterm\n.. versionadded:: 2.6\n\nMiniterm is now available as module instead of example.\nsee :ref:`miniterm` for details.\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/documentation/shortintro.rst",
    "content": "====================\n Short introduction\n====================\n\nOpening serial ports\n====================\n\nOpen port 0 at \"9600,8,N,1\", no timeout::\n\n    >>> import serial\n    >>> ser = serial.Serial(0)  # open first serial port\n    >>> print ser.portstr       # check which port was really used\n    >>> ser.write(\"hello\")      # write a string\n    >>> ser.close()             # close port\n\nOpen named port at \"19200,8,N,1\", 1s timeout::\n\n    >>> ser = serial.Serial('/dev/ttyS1', 19200, timeout=1)\n    >>> x = ser.read()          # read one byte\n    >>> s = ser.read(10)        # read up to ten bytes (timeout)\n    >>> line = ser.readline()   # read a '\\n' terminated line\n    >>> ser.close()\n\nOpen second port at \"38400,8,E,1\", non blocking HW handshaking::\n\n    >>> ser = serial.Serial(1, 38400, timeout=0,\n    ...                     parity=serial.PARITY_EVEN, rtscts=1)\n    >>> s = ser.read(100)       # read up to one hundred bytes\n    ...                         # or as much is in the buffer\n\nConfiguring ports later\n=======================\n\nGet a Serial instance and configure/open it later::\n\n    >>> ser = serial.Serial()\n    >>> ser.baudrate = 19200\n    >>> ser.port = 0\n    >>> ser\n    Serial<id=0xa81c10, open=False>(port='COM1', baudrate=19200, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=0, rtscts=0)\n    >>> ser.open()\n    >>> ser.isOpen()\n    True\n    >>> ser.close()\n    >>> ser.isOpen()\n    False\n\nReadline\n========\nBe carefully when using :meth:`readline`. Do specify a timeout when opening the\nserial port otherwise it could block forever if no newline character is\nreceived. Also note that :meth:`readlines` only works with a timeout.\n:meth:`readlines` depends on having a timeout and interprets that as EOF (end\nof file). It raises an exception if the port is not opened correctly.\n\nDo also have a look at the example files in the examples directory in the\nsource distribution or online.\n\n.. note::\n\n    The ``eol`` parameter for :meth:`readline` is no longer supported when\n    pySerial is run with newer Python versions (V2.6+) where the module\n    :mod:`io` is available.\n\nEOL\n---\nTo specify the EOL character for :meth:`readline` or to use universal newline\nmode, it is advised to use io.TextIOWrapper_::\n\n        import serial\n        import io\n        ser = serial.serial_for_url('loop://', timeout=1)\n        sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser))\n\n        sio.write(unicode(\"hello\\n\"))\n        sio.flush() # it is buffering. required to get the data out *now*\n        hello = sio.readline()\n        print hello == unicode(\"hello\\n\")\n\n\n.. _io.TextIOWrapper: http://docs.python.org/library/io.html#io.TextIOWrapper\n\n\nTesting ports\n=============\nListing ports\n-------------\n``python -m serial.tools.list_ports`` will print a list of available ports. It\nis also possible to add a regexp as first argument and the list will only\ninclude entries that matched.\n\n.. note::\n\n    The enumeration may not work on all operating systems. It may be\n    incomplete, list unavailable ports or may lack detailed descriptions of the\n    ports.\n\n.. versionadded: 2.6\n\nAccessing ports\n---------------\npySerial includes a small terminal console based terminal program called\n:ref:`miniterm`.  It ca be started with ``python -m serial.tools.miniterm <port name>``\n(use option ``-h`` to get a listing of all options).\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/enhancedserial.py",
    "content": "#!/usr/bin/env python\n\"\"\"Enhanced Serial Port class\npart of pyserial (http://pyserial.sf.net)  (C)2002 cliechti@gmx.net\n\nanother implementation of the readline and readlines method.\nthis one should be more efficient because a bunch of characters are read\non each access, but the drawback is that a timeout must be specified to\nmake it work (enforced by the class __init__).\n\nthis class could be enhanced with a read_until() method and more\nlike found in the telnetlib.\n\"\"\"\n\nfrom serial import Serial\n\nclass EnhancedSerial(Serial):\n    def __init__(self, *args, **kwargs):\n        #ensure that a reasonable timeout is set\n        timeout = kwargs.get('timeout',0.1)\n        if timeout < 0.01: timeout = 0.1\n        kwargs['timeout'] = timeout\n        Serial.__init__(self, *args, **kwargs)\n        self.buf = ''\n        \n    def readline(self, maxsize=None, timeout=1):\n        \"\"\"maxsize is ignored, timeout in seconds is the max time that is way for a complete line\"\"\"\n        tries = 0\n        while 1:\n            self.buf += self.read(512)\n            pos = self.buf.find('\\n')\n            if pos >= 0:\n                line, self.buf = self.buf[:pos+1], self.buf[pos+1:]\n                return line\n            tries += 1\n            if tries * self.timeout > timeout:\n                break\n        line, self.buf = self.buf, ''\n        return line\n\n    def readlines(self, sizehint=None, timeout=1):\n        \"\"\"read all lines that are available. abort after timout\n        when no more data arrives.\"\"\"\n        lines = []\n        while 1:\n            line = self.readline(timeout=timeout)\n            if line:\n                lines.append(line)\n            if not line or line[-1:] != '\\n':\n                break\n        return lines\n\nif __name__=='__main__':\n    #do some simple tests with a Loopback HW (see test.py for details)\n    PORT = 0\n    #test, only with Loopback HW (shortcut RX/TX pins (3+4 on DSUB 9 and 25) )\n    s = EnhancedSerial(PORT)\n    #write out some test data lines\n    s.write('\\n'.join(\"hello how are you\".split()))\n    #and read them back\n    print s.readlines()\n    #this one should print an empty list\n    print s.readlines(timeout=0.4)\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/port_publisher.py",
    "content": "#! /usr/bin/env python\n\"\"\"\\\nMulti-port serial<->TCP/IP forwarder.\n- RFC 2217\n- check existence of serial port periodically\n- start/stop forwarders\n- each forwarder creates a server socket and opens the serial port\n- serial ports are opened only once. network connect/disconnect\n  does not influence serial port\n- only one client per connection\n\"\"\"\nimport sys, os, time\nimport traceback\nimport socket\nimport select\n\nimport serial\nimport serial.rfc2217\n\nimport avahi\nimport dbus\n\nclass ZeroconfService:\n    \"\"\"\\\n    A simple class to publish a network service with zeroconf using avahi.\n    \"\"\"\n\n    def __init__(self, name, port, stype=\"_http._tcp\",\n                 domain=\"\", host=\"\", text=\"\"):\n        self.name = name\n        self.stype = stype\n        self.domain = domain\n        self.host = host\n        self.port = port\n        self.text = text\n        self.group = None\n\n    def publish(self):\n        bus = dbus.SystemBus()\n        server = dbus.Interface(\n            bus.get_object(\n                avahi.DBUS_NAME,\n                avahi.DBUS_PATH_SERVER\n            ),\n            avahi.DBUS_INTERFACE_SERVER\n        )\n\n        g = dbus.Interface(\n            bus.get_object(\n                avahi.DBUS_NAME,\n                server.EntryGroupNew()\n            ),\n            avahi.DBUS_INTERFACE_ENTRY_GROUP\n        )\n\n        g.AddService(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, dbus.UInt32(0),\n                     self.name, self.stype, self.domain, self.host,\n                     dbus.UInt16(self.port), self.text)\n\n        g.Commit()\n        self.group = g\n\n    def unpublish(self):\n        if self.group is not None:\n            self.group.Reset()\n            self.group = None\n\n    def __str__(self):\n        return \"%r @ %s:%s (%s)\" % (self.name, self.host, self.port, self.stype)\n\n\n\nclass Forwarder(ZeroconfService):\n    \"\"\"\\\n    Single port serial<->TCP/IP forarder that depends on an external select\n    loop.\n    - Buffers for serial -> network and network -> serial\n    - RFC 2217 state\n    - Zeroconf publish/unpublish on open/close.\n    \"\"\"\n\n    def __init__(self, device, name, network_port, on_close=None):\n        ZeroconfService.__init__(self, name, network_port, stype='_serial_port._tcp')\n        self.alive = False\n        self.network_port = network_port\n        self.on_close = on_close\n        self.device = device\n        self.serial = serial.Serial()\n        self.serial.port = device\n        self.serial.baudrate = 115200\n        self.serial.timeout = 0\n        self.socket = None\n        self.server_socket = None\n        self.rfc2217 = None # instantiate later, when connecting\n\n    def __del__(self):\n        try:\n            if self.alive: self.close()\n        except:\n            pass # XXX errors on shutdown\n\n    def open(self):\n        \"\"\"open serial port, start network server and publish service\"\"\"\n        self.buffer_net2ser = ''\n        self.buffer_ser2net = ''\n\n        # open serial port\n        try:\n            self.serial.open()\n            self.serial.setRTS(False)\n        except Exception, msg:\n            self.handle_serial_error(msg)\n\n        self.serial_settings_backup = self.serial.getSettingsDict()\n\n        # start the socket server\n        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n        self.server_socket.setsockopt(\n            socket.SOL_SOCKET,\n            socket.SO_REUSEADDR,\n            self.server_socket.getsockopt(\n                socket.SOL_SOCKET,\n                socket.SO_REUSEADDR\n            ) | 1\n        )\n        self.server_socket.setblocking(0)\n        try:\n            self.server_socket.bind( ('', self.network_port) )\n            self.server_socket.listen(1)\n        except socket.error, msg:\n            self.handle_server_error()\n            #~ raise\n        if not options.quiet:\n            print \"%s: Waiting for connection on %s...\" % (self.device, self.network_port)\n\n        # zeroconfig\n        self.publish()\n\n        # now we are ready\n        self.alive = True\n\n    def close(self):\n        \"\"\"Close all resources and unpublish service\"\"\"\n        if not options.quiet:\n            print \"%s: closing...\" % (self.device, )\n        self.alive = False\n        self.unpublish()\n        if self.server_socket: self.server_socket.close()\n        if self.socket:\n            self.handle_disconnect()\n        self.serial.close()\n        if self.on_close is not None:\n            # ensure it is only called once\n            callback = self.on_close\n            self.on_close = None\n            callback(self)\n\n    def write(self, data):\n        \"\"\"the write method is used by serial.rfc2217.PortManager. it has to\n        write to the network.\"\"\"\n        self.buffer_ser2net += data\n\n    def update_select_maps(self, read_map, write_map, error_map):\n        \"\"\"Update dictionaries for select call. insert fd->callback mapping\"\"\"\n        if self.alive:\n            # always handle serial port reads\n            read_map[self.serial] = self.handle_serial_read\n            error_map[self.serial] = self.handle_serial_error\n            # handle serial port writes if buffer is not empty\n            if self.buffer_net2ser:\n                write_map[self.serial] = self.handle_serial_write\n            # handle network\n            if self.socket is not None:\n                # handle socket if connected\n                # only read from network if the internal buffer is not\n                # already filled. the TCP flow control will hold back data\n                if len(self.buffer_net2ser) < 2048:\n                    read_map[self.socket] = self.handle_socket_read\n                # only check for write readiness when there is data\n                if self.buffer_ser2net:\n                    write_map[self.socket] = self.handle_socket_write\n                error_map[self.socket] = self.handle_socket_error\n            else:\n                # no connection, ensure clear buffer\n                self.buffer_ser2net = ''\n            # check the server socket\n            read_map[self.server_socket] = self.handle_connect\n            error_map[self.server_socket] = self.handle_server_error\n\n\n    def handle_serial_read(self):\n        \"\"\"Reading from serial port\"\"\"\n        try:\n            data = os.read(self.serial.fileno(), 1024)\n            if data:\n                # store data in buffer if there is a client connected\n                if self.socket is not None:\n                    # escape outgoing data when needed (Telnet IAC (0xff) character)\n                    if self.rfc2217:\n                        data = serial.to_bytes(self.rfc2217.escape(data))\n                    self.buffer_ser2net += data\n            else:\n                self.handle_serial_error()\n        except Exception, msg:\n            self.handle_serial_error(msg)\n\n    def handle_serial_write(self):\n        \"\"\"Writing to serial port\"\"\"\n        try:\n            # write a chunk\n            n = os.write(self.serial.fileno(), self.buffer_net2ser)\n            # and see how large that chunk was, remove that from buffer\n            self.buffer_net2ser = self.buffer_net2ser[n:]\n        except Exception, msg:\n            self.handle_serial_error(msg)\n\n    def handle_serial_error(self, error=None):\n        \"\"\"Serial port error\"\"\"\n        # terminate connection\n        self.close()\n\n    def handle_socket_read(self):\n        \"\"\"Read from socket\"\"\"\n        try:\n            # read a chunk from the serial port\n            data = self.socket.recv(1024)\n            if data:\n                # Process RFC 2217 stuff when enabled\n                if self.rfc2217:\n                    data = serial.to_bytes(self.rfc2217.filter(data))\n                # add data to buffer\n                self.buffer_net2ser += data\n            else:\n                # empty read indicates disconnection\n                self.handle_disconnect()\n        except socket.error:\n            self.handle_socket_error()\n\n    def handle_socket_write(self):\n        \"\"\"Write to socket\"\"\"\n        try:\n            # write a chunk\n            count = self.socket.send(self.buffer_ser2net)\n            # and remove the sent data from the buffer\n            self.buffer_ser2net = self.buffer_ser2net[count:]\n        except socket.error:\n            self.handle_socket_error()\n\n    def handle_socket_error(self):\n        \"\"\"Socket connection fails\"\"\"\n        self.handle_disconnect()\n\n    def handle_connect(self):\n        \"\"\"Server socket gets a connection\"\"\"\n        # accept a connection in any case, close connection\n        # below if already busy\n        connection, addr = self.server_socket.accept()\n        if self.socket is None:\n            self.socket = connection\n            self.socket.setblocking(0)\n            self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)\n            if not options.quiet:\n                print '%s: Connected by %s:%s' % (self.device, addr[0], addr[1])\n            self.serial.setRTS(True)\n            self.serial.setDTR(True)\n            self.rfc2217 = serial.rfc2217.PortManager(self.serial, self)\n        else:\n            # reject connection if there is already one\n            connection.close()\n            if not options.quiet:\n                print '%s: Rejecting connect from %s:%s' % (self.device, addr[0], addr[1])\n\n    def handle_server_error(self):\n        \"\"\"Socket server fails\"\"\"\n        self.close()\n\n    def handle_disconnect(self):\n        \"\"\"Socket gets disconnected\"\"\"\n        # signal disconnected terminal with control lines\n        try:\n            self.serial.setRTS(False)\n            self.serial.setDTR(False)\n        finally:\n            # restore original port configuration in case it was changed\n            self.serial.applySettingsDict(self.serial_settings_backup)\n            # stop RFC 2217 state machine\n            self.rfc2217 = None\n            # clear send buffer\n            self.buffer_ser2net = ''\n            # close network connection\n            if self.socket is not None:\n                self.socket.close()\n                self.socket = None\n                if not options.quiet:\n                    print '%s: Disconnected' % self.device\n\n\ndef test():\n    service = ZeroconfService(name=\"TestService\", port=3000)\n    service.publish()\n    raw_input(\"Press any key to unpublish the service \")\n    service.unpublish()\n\n\nif __name__ == '__main__':\n    import optparse\n\n    parser = optparse.OptionParser(usage=\"\"\"\\\n%prog [options]\n\nAnnounce the existence of devices using zeroconf and provide\na TCP/IP <-> serial port gateway (implements RFC 2217).\n\nNote that the TCP/IP server is not protected. Everyone can connect\nto it!\n\nIf running as daemon, write to syslog. Otherwise write to stdout.\n\"\"\")\n\n    parser.add_option(\"-q\", \"--quiet\", dest=\"quiet\", action=\"store_true\",\n        help=\"suppress non error messages\", default=False)\n\n    parser.add_option(\"-o\", \"--logfile\", dest=\"log_file\",\n        help=\"write messages file instead of stdout\", default=None, metavar=\"FILE\")\n\n    parser.add_option(\"-d\", \"--daemon\", dest=\"daemonize\", action=\"store_true\",\n            help=\"start as daemon\", default=False)\n\n    parser.add_option(\"\", \"--pidfile\", dest=\"pid_file\",\n        help=\"specify a name for the PID file\", default=None, metavar=\"FILE\")\n\n    (options, args) = parser.parse_args()\n\n    # redirect output if specified\n    if options.log_file is not None:\n        class WriteFlushed:\n            def __init__(self, fileobj):\n                self.fileobj = fileobj\n            def write(self, s):\n                self.fileobj.write(s)\n                self.fileobj.flush()\n            def close(self):\n                self.fileobj.close()\n                sys.stdout = sys.stderr = WriteFlushed(open(options.log_file, 'a'))\n        # atexit.register(lambda: sys.stdout.close())\n\n    if options.daemonize:\n        # if running as daemon is requested, do the fork magic\n        # options.quiet = True\n        import pwd\n        # do the UNIX double-fork magic, see Stevens' \"Advanced\n        # Programming in the UNIX Environment\" for details (ISBN 0201563177)\n        try:\n            pid = os.fork()\n            if pid > 0:\n                # exit first parent\n                sys.exit(0)\n        except OSError, e:\n            sys.stderr.write(\"fork #1 failed: %d (%s)\\n\" % (e.errno, e.strerror))\n            sys.exit(1)\n\n        # decouple from parent environment\n        os.chdir(\"/\")   # don't prevent unmounting....\n        os.setsid()\n        os.umask(0)\n\n        # do second fork\n        try:\n            pid = os.fork()\n            if pid > 0:\n                # exit from second parent, print eventual PID before\n                # print \"Daemon PID %d\" % pid\n                if options.pid_file is not None:\n                    open(options.pid_file,'w').write(\"%d\"%pid)\n                sys.exit(0)\n        except OSError, e:\n            sys.stderr.write(\"fork #2 failed: %d (%s)\\n\" % (e.errno, e.strerror))\n            sys.exit(1)\n\n        if options.log_file is None:\n            import syslog\n            syslog.openlog(\"serial port publisher\")\n            # redirect output to syslog\n            class WriteToSysLog:\n                def __init__(self):\n                    self.buffer = ''\n                def write(self, s):\n                    self.buffer += s\n                    if '\\n' in self.buffer:\n                        output, self.buffer = self.buffer.split('\\n', 1)\n                        syslog.syslog(output)\n                def flush(self):\n                    syslog.syslog(self.buffer)\n                    self.buffer = ''\n                def close(self):\n                    self.flush()\n            sys.stdout = sys.stderr = WriteToSysLog()\n\n            # ensure the that the daemon runs a normal user, if run as root\n        #if os.getuid() == 0:\n            #    name, passwd, uid, gid, desc, home, shell = pwd.getpwnam('someuser')\n            #    os.setgid(gid)     # set group first\n            #    os.setuid(uid)     # set user\n\n    # keep the published stuff in a dictionary\n    published = {}\n    # prepare list of device names (hard coded)\n    device_list = ['/dev/ttyUSB%d' % p for p in range(8)]\n    # get a nice hostname\n    hostname = socket.gethostname()\n\n    def unpublish(forwarder):\n        \"\"\"when forwarders die, we need to unregister them\"\"\"\n        try:\n            del published[forwarder.device]\n        except KeyError:\n            pass\n        else:\n            if not options.quiet: print \"unpublish: %s\" % (forwarder)\n\n    alive = True\n    next_check = 0\n    # main loop\n    while alive:\n        try:\n            # if it is time, check for serial port devices\n            now = time.time()\n            if now > next_check:\n                next_check = now + 5\n                # check each device\n                for device in device_list:\n                    # if it appeared\n                    if os.path.exists(device):\n                        if device not in published:\n                            num = int(device[-1])\n                            published[device] = Forwarder(\n                                device,\n                                \"%s on %s\" % (device, hostname),\n                                7000+num,\n                                on_close=unpublish\n                            )\n                            if not options.quiet: print \"publish: %s\" % (published[device])\n                            published[device].open()\n                    else:\n                        # or when it disappeared\n                        if device in published:\n                            if not options.quiet: print \"unpublish: %s\" % (published[device])\n                            published[device].close()\n                            try:\n                                del published[device]\n                            except KeyError:\n                                pass\n\n            # select_start = time.time()\n            read_map = {}\n            write_map = {}\n            error_map = {}\n            for publisher in published.values():\n                publisher.update_select_maps(read_map, write_map, error_map)\n            try:\n                readers, writers, errors = select.select(\n                    read_map.keys(),\n                    write_map.keys(),\n                    error_map.keys(),\n                    5\n                )\n            except select.error, err:\n                if err[0] != EINTR:\n                    raise\n            # select_end = time.time()\n            # print \"select used %.3f s\" % (select_end - select_start)\n            for reader in readers:\n                read_map[reader]()\n            for writer in writers:\n                write_map[writer]()\n            for error in errors:\n                error_map[error]()\n            # print \"operation used %.3f s\" % (time.time() - select_end)\n        except KeyboardInterrupt:\n            alive = False\n        except SystemExit:\n            raise\n        except:\n            #~ raise\n            traceback.print_exc()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/port_publisher.sh",
    "content": "#! /bin/sh\n# daemon starter script\n# based on skeleton from Debian GNU/Linux\n# cliechti at gmx.net\n\nPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\nDAEMON=/usr/local/bin/port_publisher.py\nNAME=port_publisher\nDESC=\"serial port avahi device publisher\"\n\ntest -f $DAEMON || exit 0\n\nset -e\n\ncase \"$1\" in\n    start)\n        echo -n \"Starting $DESC: \"\n        $DAEMON --daemon --pidfile /var/run/$NAME.pid\n        echo \"$NAME.\"\n        ;;\n    stop)\n        echo -n \"Stopping $DESC: \"\n        start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid\n        # \\     --exec $DAEMON\n        echo \"$NAME.\"\n        ;;\n    restart|force-reload)\n        echo -n \"Restarting $DESC: \"\n        start-stop-daemon --stop --quiet --pidfile \\\n                /var/run/$NAME.pid\n                # --exec $DAEMON\n        sleep 1\n        $DAEMON --daemon --pidfile /var/run/$NAME.pid\n        echo \"$NAME.\"\n        ;;\n    *)\n        N=/etc/init.d/$NAME\n        echo \"Usage: $N {start|stop|restart|force-reload}\" >&2\n        exit 1\n        ;;\nesac\n\nexit 0\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/rfc2217_server.py",
    "content": "#!/usr/bin/env python\n\n# (C) 2009 Chris Liechti <cliechti@gmx.net>\n# redirect data from a TCP/IP connection to a serial port and vice versa\n# using RFC 2217\n\n\nimport sys\nimport os\nimport threading\nimport time\nimport socket\nimport serial\nimport serial.rfc2217\nimport logging\n\nclass Redirector:\n    def __init__(self, serial_instance, socket, debug=None):\n        self.serial = serial_instance\n        self.socket = socket\n        self._write_lock = threading.Lock()\n        self.rfc2217 = serial.rfc2217.PortManager(\n            self.serial,\n            self,\n            logger = (debug and logging.getLogger('rfc2217.server'))\n            )\n        self.log = logging.getLogger('redirector')\n\n    def statusline_poller(self):\n        self.log.debug('status line poll thread started')\n        while self.alive:\n            time.sleep(1)\n            self.rfc2217.check_modem_lines()\n        self.log.debug('status line poll thread terminated')\n\n    def shortcut(self):\n        \"\"\"connect the serial port to the TCP port by copying everything\n           from one side to the other\"\"\"\n        self.alive = True\n        self.thread_read = threading.Thread(target=self.reader)\n        self.thread_read.setDaemon(True)\n        self.thread_read.setName('serial->socket')\n        self.thread_read.start()\n        self.thread_poll = threading.Thread(target=self.statusline_poller)\n        self.thread_poll.setDaemon(True)\n        self.thread_poll.setName('status line poll')\n        self.thread_poll.start()\n        self.writer()\n\n    def reader(self):\n        \"\"\"loop forever and copy serial->socket\"\"\"\n        self.log.debug('reader thread started')\n        while self.alive:\n            try:\n                data = self.serial.read(1)              # read one, blocking\n                n = self.serial.inWaiting()             # look if there is more\n                if n:\n                    data = data + self.serial.read(n)   # and get as much as possible\n                if data:\n                    # escape outgoing data when needed (Telnet IAC (0xff) character)\n                    data = serial.to_bytes(self.rfc2217.escape(data))\n                    self._write_lock.acquire()\n                    try:\n                        self.socket.sendall(data)       # send it over TCP\n                    finally:\n                        self._write_lock.release()\n            except socket.error, msg:\n                self.log.error('%s' % (msg,))\n                # probably got disconnected\n                break\n        self.alive = False\n        self.log.debug('reader thread terminated')\n\n    def write(self, data):\n        \"\"\"thread safe socket write with no data escaping. used to send telnet stuff\"\"\"\n        self._write_lock.acquire()\n        try:\n            self.socket.sendall(data)\n        finally:\n            self._write_lock.release()\n\n    def writer(self):\n        \"\"\"loop forever and copy socket->serial\"\"\"\n        while self.alive:\n            try:\n                data = self.socket.recv(1024)\n                if not data:\n                    break\n                self.serial.write(serial.to_bytes(self.rfc2217.filter(data)))\n            except socket.error, msg:\n                self.log.error('%s' % (msg,))\n                # probably got disconnected\n                break\n        self.stop()\n\n    def stop(self):\n        \"\"\"Stop copying\"\"\"\n        self.log.debug('stopping')\n        if self.alive:\n            self.alive = False\n            self.thread_read.join()\n            self.thread_poll.join()\n\n\nif __name__ == '__main__':\n    import optparse\n\n    parser = optparse.OptionParser(\n        usage = \"%prog [options] port\",\n        description = \"RFC 2217 Serial to Network (TCP/IP) redirector.\",\n        epilog = \"\"\"\\\nNOTE: no security measures are implemented. Anyone can remotely connect\nto this service over the network.\n\nOnly one connection at once is supported. When the connection is terminated\nit waits for the next connect.\n\"\"\")\n\n    parser.add_option(\"-p\", \"--localport\",\n        dest = \"local_port\",\n        action = \"store\",\n        type = 'int',\n        help = \"local TCP port\",\n        default = 2217\n    )\n\n    parser.add_option(\"-v\", \"--verbose\",\n        dest = \"verbosity\",\n        action = \"count\",\n        help = \"print more diagnostic messages (option can be given multiple times)\",\n        default = 0\n    )\n\n    (options, args) = parser.parse_args()\n\n    if len(args) != 1:\n        parser.error('serial port name required as argument')\n\n    if options.verbosity > 3:\n        options.verbosity = 3\n    level = (\n        logging.WARNING,\n        logging.INFO,\n        logging.DEBUG,\n        logging.NOTSET,\n        )[options.verbosity]\n    logging.basicConfig(level=logging.INFO)\n    logging.getLogger('root').setLevel(logging.INFO)\n    logging.getLogger('rfc2217').setLevel(level)\n\n    # connect to serial port\n    ser = serial.Serial()\n    ser.port     = args[0]\n    ser.timeout  = 3     # required so that the reader thread can exit\n\n    logging.info(\"RFC 2217 TCP/IP to Serial redirector - type Ctrl-C / BREAK to quit\")\n\n    try:\n        ser.open()\n    except serial.SerialException, e:\n        logging.error(\"Could not open serial port %s: %s\" % (ser.portstr, e))\n        sys.exit(1)\n\n    logging.info(\"Serving serial port: %s\" % (ser.portstr,))\n    settings = ser.getSettingsDict()\n    # reset control line as no _remote_ \"terminal\" has been connected yet\n    ser.setDTR(False)\n    ser.setRTS(False)\n\n    srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n    srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n    srv.bind( ('', options.local_port) )\n    srv.listen(1)\n    logging.info(\"TCP/IP port: %s\" % (options.local_port,))\n    while True:\n        try:\n            connection, addr = srv.accept()\n            logging.info('Connected by %s:%s' % (addr[0], addr[1]))\n            connection.setsockopt( socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)\n            ser.setRTS(True)\n            ser.setDTR(True)\n            # enter network <-> serial loop\n            r = Redirector(\n                ser,\n                connection,\n                options.verbosity > 0\n            )\n            try:\n                r.shortcut()\n            finally:\n                logging.info('Disconnected')\n                r.stop()\n                connection.close()\n                ser.setDTR(False)\n                ser.setRTS(False)\n            # Restore port settings (may have been changed by RFC 2217 capable\n            # client)\n            ser.applySettingsDict(settings)\n        except KeyboardInterrupt:\n            break\n        except socket.error, msg:\n            logging.error('%s' % (msg,))\n\n    logging.info('--- exit ---')\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/scan.py",
    "content": "#! /usr/bin/env python\n\"\"\"\\\nScan for serial ports.\n\nPart of pySerial (http://pyserial.sf.net)\n(C) 2002-2003 <cliechti@gmx.net>\n\nThe scan function of this module tries to open each port number\nfrom 0 to 255 and it builds a list of those ports where this was\nsuccessful.\n\"\"\"\n\nimport serial\n\ndef scan():\n    \"\"\"scan for available ports. return a list of tuples (num, name)\"\"\"\n    available = []\n    for i in range(256):\n        try:\n            s = serial.Serial(i)\n            available.append( (i, s.portstr))\n            s.close()   # explicit close 'cause of delayed GC in java\n        except serial.SerialException:\n            pass\n    return available\n\nif __name__=='__main__':\n    print \"Found ports:\"\n    for n,s in scan():\n        print \"(%d) %s\" % (n,s)\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/scanlinux.py",
    "content": "#! /usr/bin/env python\n\"\"\"\\\nScan for serial ports. Linux specific variant that also includes USB/Serial\nadapters.\n\nPart of pySerial (http://pyserial.sf.net)\n(C) 2009 <cliechti@gmx.net>\n\"\"\"\n\nimport serial\nimport glob\n\ndef scan():\n    \"\"\"scan for available ports. return a list of device names.\"\"\"\n    return glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*')\n\nif __name__=='__main__':\n    print \"Found ports:\"\n    for name in scan():\n        print name\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/scanwin32.py",
    "content": "import ctypes\nimport re\n\ndef ValidHandle(value):\n    if value == 0:\n        raise ctypes.WinError()\n    return value\n\nNULL = 0\nHDEVINFO = ctypes.c_int\nBOOL = ctypes.c_int\nCHAR = ctypes.c_char\nPCTSTR = ctypes.c_char_p\nHWND = ctypes.c_uint\nDWORD = ctypes.c_ulong\nPDWORD = ctypes.POINTER(DWORD)\nULONG = ctypes.c_ulong\nULONG_PTR = ctypes.POINTER(ULONG)\n#~ PBYTE = ctypes.c_char_p\nPBYTE = ctypes.c_void_p\n\nclass GUID(ctypes.Structure):\n    _fields_ = [\n        ('Data1', ctypes.c_ulong),\n        ('Data2', ctypes.c_ushort),\n        ('Data3', ctypes.c_ushort),\n        ('Data4', ctypes.c_ubyte*8),\n    ]\n    def __str__(self):\n        return \"{%08x-%04x-%04x-%s-%s}\" % (\n            self.Data1,\n            self.Data2,\n            self.Data3,\n            ''.join([\"%02x\" % d for d in self.Data4[:2]]),\n            ''.join([\"%02x\" % d for d in self.Data4[2:]]),\n        )\n\nclass SP_DEVINFO_DATA(ctypes.Structure):\n    _fields_ = [\n        ('cbSize', DWORD),\n        ('ClassGuid', GUID),\n        ('DevInst', DWORD),\n        ('Reserved', ULONG_PTR),\n    ]\n    def __str__(self):\n        return \"ClassGuid:%s DevInst:%s\" % (self.ClassGuid, self.DevInst)\nPSP_DEVINFO_DATA = ctypes.POINTER(SP_DEVINFO_DATA)\n\nclass SP_DEVICE_INTERFACE_DATA(ctypes.Structure):\n    _fields_ = [\n        ('cbSize', DWORD),\n        ('InterfaceClassGuid', GUID),\n        ('Flags', DWORD),\n        ('Reserved', ULONG_PTR),\n    ]\n    def __str__(self):\n        return \"InterfaceClassGuid:%s Flags:%s\" % (self.InterfaceClassGuid, self.Flags)\n\nPSP_DEVICE_INTERFACE_DATA = ctypes.POINTER(SP_DEVICE_INTERFACE_DATA)\n\nPSP_DEVICE_INTERFACE_DETAIL_DATA = ctypes.c_void_p\n\nclass dummy(ctypes.Structure):\n    _fields_=[(\"d1\", DWORD), (\"d2\", CHAR)]\n    _pack_ = 1\nSIZEOF_SP_DEVICE_INTERFACE_DETAIL_DATA_A = ctypes.sizeof(dummy)\n\nSetupDiDestroyDeviceInfoList = ctypes.windll.setupapi.SetupDiDestroyDeviceInfoList\nSetupDiDestroyDeviceInfoList.argtypes = [HDEVINFO]\nSetupDiDestroyDeviceInfoList.restype = BOOL\n\nSetupDiGetClassDevs = ctypes.windll.setupapi.SetupDiGetClassDevsA\nSetupDiGetClassDevs.argtypes = [ctypes.POINTER(GUID), PCTSTR, HWND, DWORD]\nSetupDiGetClassDevs.restype = ValidHandle # HDEVINFO\n\nSetupDiEnumDeviceInterfaces = ctypes.windll.setupapi.SetupDiEnumDeviceInterfaces\nSetupDiEnumDeviceInterfaces.argtypes = [HDEVINFO, PSP_DEVINFO_DATA, ctypes.POINTER(GUID), DWORD, PSP_DEVICE_INTERFACE_DATA]\nSetupDiEnumDeviceInterfaces.restype = BOOL\n\nSetupDiGetDeviceInterfaceDetail = ctypes.windll.setupapi.SetupDiGetDeviceInterfaceDetailA\nSetupDiGetDeviceInterfaceDetail.argtypes = [HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA, DWORD, PDWORD, PSP_DEVINFO_DATA]\nSetupDiGetDeviceInterfaceDetail.restype = BOOL\n\nSetupDiGetDeviceRegistryProperty = ctypes.windll.setupapi.SetupDiGetDeviceRegistryPropertyA\nSetupDiGetDeviceRegistryProperty.argtypes = [HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD]\nSetupDiGetDeviceRegistryProperty.restype = BOOL\n\n\nGUID_CLASS_COMPORT = GUID(0x86e0d1e0L, 0x8089, 0x11d0,\n    (ctypes.c_ubyte*8)(0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73))\n\nDIGCF_PRESENT = 2\nDIGCF_DEVICEINTERFACE = 16\nINVALID_HANDLE_VALUE = 0\nERROR_INSUFFICIENT_BUFFER = 122\nSPDRP_HARDWAREID = 1\nSPDRP_FRIENDLYNAME = 12\nSPDRP_LOCATION_INFORMATION = 13\nERROR_NO_MORE_ITEMS = 259\n\ndef comports(available_only=True):\n    \"\"\"This generator scans the device registry for com ports and yields\n    (order, port, desc, hwid).  If available_only is true only return currently\n    existing ports. Order is a helper to get sorted lists. it can be ignored\n    otherwise.\"\"\"\n    flags = DIGCF_DEVICEINTERFACE\n    if available_only:\n        flags |= DIGCF_PRESENT\n    g_hdi = SetupDiGetClassDevs(ctypes.byref(GUID_CLASS_COMPORT), None, NULL, flags);\n    #~ for i in range(256):\n    for dwIndex in range(256):\n        did = SP_DEVICE_INTERFACE_DATA()\n        did.cbSize = ctypes.sizeof(did)\n\n        if not SetupDiEnumDeviceInterfaces(\n            g_hdi,\n            None,\n            ctypes.byref(GUID_CLASS_COMPORT),\n            dwIndex,\n            ctypes.byref(did)\n        ):\n            if ctypes.GetLastError() != ERROR_NO_MORE_ITEMS:\n                raise ctypes.WinError()\n            break\n\n        dwNeeded = DWORD()\n        # get the size\n        if not SetupDiGetDeviceInterfaceDetail(\n            g_hdi,\n            ctypes.byref(did),\n            None, 0, ctypes.byref(dwNeeded),\n            None\n        ):\n            # Ignore ERROR_INSUFFICIENT_BUFFER\n            if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:\n                raise ctypes.WinError()\n        # allocate buffer\n        class SP_DEVICE_INTERFACE_DETAIL_DATA_A(ctypes.Structure):\n            _fields_ = [\n                ('cbSize', DWORD),\n                ('DevicePath', CHAR*(dwNeeded.value - ctypes.sizeof(DWORD))),\n            ]\n            def __str__(self):\n                return \"DevicePath:%s\" % (self.DevicePath,)\n        idd = SP_DEVICE_INTERFACE_DETAIL_DATA_A()\n        idd.cbSize = SIZEOF_SP_DEVICE_INTERFACE_DETAIL_DATA_A\n        devinfo = SP_DEVINFO_DATA()\n        devinfo.cbSize = ctypes.sizeof(devinfo)\n        if not SetupDiGetDeviceInterfaceDetail(\n            g_hdi,\n            ctypes.byref(did),\n            ctypes.byref(idd), dwNeeded, None,\n            ctypes.byref(devinfo)\n        ):\n            raise ctypes.WinError()\n\n        # hardware ID\n        szHardwareID = ctypes.create_string_buffer(250)\n        if not SetupDiGetDeviceRegistryProperty(\n            g_hdi,\n            ctypes.byref(devinfo),\n            SPDRP_HARDWAREID,\n            None,\n            ctypes.byref(szHardwareID), ctypes.sizeof(szHardwareID) - 1,\n            None\n        ):\n            # Ignore ERROR_INSUFFICIENT_BUFFER\n            if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:\n                raise ctypes.WinError()\n\n        # friendly name\n        szFriendlyName = ctypes.create_string_buffer(1024)\n        if not SetupDiGetDeviceRegistryProperty(\n            g_hdi,\n            ctypes.byref(devinfo),\n            SPDRP_FRIENDLYNAME,\n            None,\n            ctypes.byref(szFriendlyName), ctypes.sizeof(szFriendlyName) - 1,\n            None\n        ):\n            # Ignore ERROR_INSUFFICIENT_BUFFER\n            if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:\n                #~ raise ctypes.WinError()\n                # not getting friendly name for com0com devices, try something else\n                szFriendlyName = ctypes.create_string_buffer(1024)\n                if SetupDiGetDeviceRegistryProperty(\n                    g_hdi,\n                    ctypes.byref(devinfo),\n                    SPDRP_LOCATION_INFORMATION,\n                    None,\n                    ctypes.byref(szFriendlyName), ctypes.sizeof(szFriendlyName) - 1,\n                    None\n                ):\n                    port_name = \"\\\\\\\\.\\\\\" + szFriendlyName.value\n                    order = None\n                else:\n                    port_name = szFriendlyName.value\n                    order = None\n        else:\n            try:\n                m = re.search(r\"\\((.*?(\\d+))\\)\", szFriendlyName.value)\n                #~ print szFriendlyName.value, m.groups()\n                port_name = m.group(1)\n                order = int(m.group(2))\n            except AttributeError, msg:\n                port_name = szFriendlyName.value\n                order = None\n        yield order, port_name, szFriendlyName.value, szHardwareID.value\n\n    SetupDiDestroyDeviceInfoList(g_hdi)\n\n\nif __name__ == '__main__':\n    import serial\n    print \"-\"*78\n    print \"Serial ports\"\n    print \"-\"*78\n    for order, port, desc, hwid in sorted(comports()):\n        print \"%-10s: %s (%s) ->\" % (port, desc, hwid),\n        try:\n            serial.Serial(port) # test open\n        except serial.serialutil.SerialException:\n            print \"can't be openend\"\n        else:\n            print \"Ready\"\n    print\n    # list of all ports the system knows\n    print \"-\"*78\n    print \"All serial ports (registry)\"\n    print \"-\"*78\n    for order, port, desc, hwid in sorted(comports(False)):\n        print \"%-10s: %s (%s)\" % (port, desc, hwid)\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/setup-miniterm-py2exe.py",
    "content": "# setup script for py2exe to create the miniterm.exe\n# $Id: setup-miniterm-py2exe.py,v 1.1 2005-09-21 19:51:19 cliechti Exp $\n\nfrom distutils.core import setup\nimport glob, sys, py2exe, os\n\nsys.path.append('..')\n\nsys.argv.extend(\"py2exe --bundle 1\".split())\n\nimport serial.tools.miniterm\n\nsetup(\n    name = 'miniterm',\n    zipfile = None,\n    options = {\"py2exe\":\n        {\n            'dist_dir': 'bin',\n            'excludes': ['serialjava', 'serialposix', 'serialcli'],\n            'compressed': 1,\n        }\n    },\n    console = [\n        #~ \"miniterm.py\",\n        serial.tools.miniterm.__file__\n    ],\n)\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/setup-rfc2217_server-py2exe.py",
    "content": "# setup script for py2exe to create the miniterm.exe\n# $Id: setup-rfc2217_server-py2exe.py 320 2009-08-07 18:22:49Z cliechti $\n\nfrom distutils.core import setup\nimport glob, sys, py2exe, os\n\nsys.path.append('..')\n\nsys.argv.extend(\"py2exe --bundle 1\".split())\n\nsetup(\n    name='rfc2217_server',\n    zipfile=None,\n    options = {\"py2exe\":\n        {\n            'dist_dir': 'bin',\n            'excludes': ['javax.comm'],\n            'compressed': 1,\n        }\n    },\n    console = [\n        \"rfc2217_server.py\",\n    ],\n)\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/setup-wxTerminal-py2exe.py",
    "content": "# This is a setup.py example script for the use with py2exe\nfrom distutils.core import setup\nimport py2exe\nimport sys, os\n\n#this script is only useful for py2exe so just run that distutils command.\n#that allows to run it with a simple double click.\nsys.argv.append('py2exe')\n\n#get an icon from somewhere.. the python installation should have one:\nicon = os.path.join(os.path.dirname(sys.executable), 'py.ico')\n\nsetup(\n    options = {'py2exe': {\n        'excludes': ['javax.comm'],\n        'optimize': 2,\n        'dist_dir': 'dist',\n        }\n    },\n\n    name = \"wxTerminal\",\n    windows = [\n        {\n            'script': \"wxTerminal.py\",\n            'icon_resources': [(0x0004, icon)]\n        },\n    ],\n    zipfile = \"stuff.lib\",\n\n    description = \"Simple serial terminal application\",\n    version = \"0.1\",\n    author = \"Chris Liechti\",\n    author_email = \"cliechti@gmx.net\",\n    url = \"http://pyserial.sf.net\",\n)\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/tcp_serial_redirect.py",
    "content": "#!/usr/bin/env python\n\n# (C) 2002-2009 Chris Liechti <cliechti@gmx.net>\n# redirect data from a TCP/IP connection to a serial port and vice versa\n# requires Python 2.2 'cause socket.sendall is used\n\n\nimport sys\nimport os\nimport time\nimport threading\nimport socket\nimport codecs\nimport serial\ntry:\n    True\nexcept NameError:\n    True = 1\n    False = 0\n\nclass Redirector:\n    def __init__(self, serial_instance, socket, ser_newline=None, net_newline=None, spy=False):\n        self.serial = serial_instance\n        self.socket = socket\n        self.ser_newline = ser_newline\n        self.net_newline = net_newline\n        self.spy = spy\n        self._write_lock = threading.Lock()\n\n    def shortcut(self):\n        \"\"\"connect the serial port to the TCP port by copying everything\n           from one side to the other\"\"\"\n        self.alive = True\n        self.thread_read = threading.Thread(target=self.reader)\n        self.thread_read.setDaemon(True)\n        self.thread_read.setName('serial->socket')\n        self.thread_read.start()\n        self.writer()\n\n    def reader(self):\n        \"\"\"loop forever and copy serial->socket\"\"\"\n        while self.alive:\n            try:\n                data = self.serial.read(1)              # read one, blocking\n                n = self.serial.inWaiting()             # look if there is more\n                if n:\n                    data = data + self.serial.read(n)   # and get as much as possible\n                if data:\n                    # the spy shows what's on the serial port, so log it before converting newlines\n                    if self.spy:\n                        sys.stdout.write(codecs.escape_encode(data)[0])\n                        sys.stdout.flush()\n                    if self.ser_newline and self.net_newline:\n                        # do the newline conversion\n                        # XXX fails for CR+LF in input when it is cut in half at the begin or end of the string\n                        data = net_newline.join(data.split(ser_newline))\n                    # escape outgoing data when needed (Telnet IAC (0xff) character)\n                    self._write_lock.acquire()\n                    try:\n                        self.socket.sendall(data)           # send it over TCP\n                    finally:\n                        self._write_lock.release()\n            except socket.error, msg:\n                sys.stderr.write('ERROR: %s\\n' % msg)\n                # probably got disconnected\n                break\n        self.alive = False\n\n    def write(self, data):\n        \"\"\"thread safe socket write with no data escaping. used to send telnet stuff\"\"\"\n        self._write_lock.acquire()\n        try:\n            self.socket.sendall(data)\n        finally:\n            self._write_lock.release()\n\n    def writer(self):\n        \"\"\"loop forever and copy socket->serial\"\"\"\n        while self.alive:\n            try:\n                data = self.socket.recv(1024)\n                if not data:\n                    break\n                if self.ser_newline and self.net_newline:\n                    # do the newline conversion\n                    # XXX fails for CR+LF in input when it is cut in half at the begin or end of the string\n                    data = ser_newline.join(data.split(net_newline))\n                self.serial.write(data)                 # get a bunch of bytes and send them\n                # the spy shows what's on the serial port, so log it after converting newlines\n                if self.spy:\n                    sys.stdout.write(codecs.escape_encode(data)[0])\n                    sys.stdout.flush()\n            except socket.error, msg:\n                sys.stderr.write('ERROR: %s\\n' % msg)\n                # probably got disconnected\n                break\n        self.alive = False\n        self.thread_read.join()\n\n    def stop(self):\n        \"\"\"Stop copying\"\"\"\n        if self.alive:\n            self.alive = False\n            self.thread_read.join()\n\n\nif __name__ == '__main__':\n    import optparse\n\n    parser = optparse.OptionParser(\n        usage = \"%prog [options] [port [baudrate]]\",\n        description = \"Simple Serial to Network (TCP/IP) redirector.\",\n        epilog = \"\"\"\\\nNOTE: no security measures are implemented. Anyone can remotely connect\nto this service over the network.\n\nOnly one connection at once is supported. When the connection is terminated\nit waits for the next connect.\n\"\"\")\n\n    parser.add_option(\"-q\", \"--quiet\",\n        dest = \"quiet\",\n        action = \"store_true\",\n        help = \"suppress non error messages\",\n        default = False\n    )\n\n    parser.add_option(\"--spy\",\n        dest = \"spy\",\n        action = \"store_true\",\n        help = \"peek at the communication and print all data to the console\",\n        default = False\n    )\n\n    group = optparse.OptionGroup(parser,\n        \"Serial Port\",\n        \"Serial port settings\"\n    )\n    parser.add_option_group(group)\n\n    group.add_option(\"-p\", \"--port\",\n        dest = \"port\",\n        help = \"port, a number (default 0) or a device name\",\n        default = None\n    )\n\n    group.add_option(\"-b\", \"--baud\",\n        dest = \"baudrate\",\n        action = \"store\",\n        type = 'int',\n        help = \"set baud rate, default: %default\",\n        default = 9600\n    )\n\n    group.add_option(\"\", \"--parity\",\n        dest = \"parity\",\n        action = \"store\",\n        help = \"set parity, one of [N, E, O], default=%default\",\n        default = 'N'\n    )\n\n    group.add_option(\"--rtscts\",\n        dest = \"rtscts\",\n        action = \"store_true\",\n        help = \"enable RTS/CTS flow control (default off)\",\n        default = False\n    )\n\n    group.add_option(\"--xonxoff\",\n        dest = \"xonxoff\",\n        action = \"store_true\",\n        help = \"enable software flow control (default off)\",\n        default = False\n    )\n\n    group.add_option(\"--rts\",\n        dest = \"rts_state\",\n        action = \"store\",\n        type = 'int',\n        help = \"set initial RTS line state (possible values: 0, 1)\",\n        default = None\n    )\n\n    group.add_option(\"--dtr\",\n        dest = \"dtr_state\",\n        action = \"store\",\n        type = 'int',\n        help = \"set initial DTR line state (possible values: 0, 1)\",\n        default = None\n    )\n\n    group = optparse.OptionGroup(parser,\n        \"Network settings\",\n        \"Network configuration.\"\n    )\n    parser.add_option_group(group)\n\n    group.add_option(\"-P\", \"--localport\",\n        dest = \"local_port\",\n        action = \"store\",\n        type = 'int',\n        help = \"local TCP port\",\n        default = 7777\n    )\n\n    group = optparse.OptionGroup(parser,\n        \"Newline Settings\",\n        \"Convert newlines between network and serial port. Conversion is normally disabled and can be enabled by --convert.\"\n    )\n    parser.add_option_group(group)\n\n    group.add_option(\"-c\", \"--convert\",\n        dest = \"convert\",\n        action = \"store_true\",\n        help = \"enable newline conversion (default off)\",\n        default = False\n    )\n\n    group.add_option(\"--net-nl\",\n        dest = \"net_newline\",\n        action = \"store\",\n        help = \"type of newlines that are expected on the network (default: %default)\",\n        default = \"LF\"\n    )\n\n    group.add_option(\"--ser-nl\",\n        dest = \"ser_newline\",\n        action = \"store\",\n        help = \"type of newlines that are expected on the serial port (default: %default)\",\n        default = \"CR+LF\"\n    )\n\n    (options, args) = parser.parse_args()\n\n    # get port and baud rate from command line arguments or the option switches\n    port = options.port\n    baudrate = options.baudrate\n    if args:\n        if options.port is not None:\n            parser.error(\"no arguments are allowed, options only when --port is given\")\n        port = args.pop(0)\n        if args:\n            try:\n                baudrate = int(args[0])\n            except ValueError:\n                parser.error(\"baud rate must be a number, not %r\" % args[0])\n            args.pop(0)\n        if args:\n            parser.error(\"too many arguments\")\n    else:\n        if port is None: port = 0\n\n    # check newline modes for network connection\n    mode = options.net_newline.upper()\n    if mode == 'CR':\n        net_newline = '\\r'\n    elif mode == 'LF':\n        net_newline = '\\n'\n    elif mode == 'CR+LF' or mode == 'CRLF':\n        net_newline = '\\r\\n'\n    else:\n        parser.error(\"Invalid value for --net-nl. Valid are 'CR', 'LF' and 'CR+LF'/'CRLF'.\")\n\n    # check newline modes for serial connection\n    mode = options.ser_newline.upper()\n    if mode == 'CR':\n        ser_newline = '\\r'\n    elif mode == 'LF':\n        ser_newline = '\\n'\n    elif mode == 'CR+LF' or mode == 'CRLF':\n        ser_newline = '\\r\\n'\n    else:\n        parser.error(\"Invalid value for --ser-nl. Valid are 'CR', 'LF' and 'CR+LF'/'CRLF'.\")\n\n    # connect to serial port\n    ser = serial.Serial()\n    ser.port     = port\n    ser.baudrate = baudrate\n    ser.parity   = options.parity\n    ser.rtscts   = options.rtscts\n    ser.xonxoff  = options.xonxoff\n    ser.timeout  = 1     # required so that the reader thread can exit\n\n    if not options.quiet:\n        sys.stderr.write(\"--- TCP/IP to Serial redirector --- type Ctrl-C / BREAK to quit\\n\")\n        sys.stderr.write(\"--- %s %s,%s,%s,%s ---\\n\" % (ser.portstr, ser.baudrate, 8, ser.parity, 1))\n\n    try:\n        ser.open()\n    except serial.SerialException, e:\n        sys.stderr.write(\"Could not open serial port %s: %s\\n\" % (ser.portstr, e))\n        sys.exit(1)\n\n    if options.rts_state is not None:\n        ser.setRTS(options.rts_state)\n\n    if options.dtr_state is not None:\n        ser.setDTR(options.dtr_state)\n\n    srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n    srv.bind( ('', options.local_port) )\n    srv.listen(1)\n    while True:\n        try:\n            sys.stderr.write(\"Waiting for connection on %s...\\n\" % options.local_port)\n            connection, addr = srv.accept()\n            sys.stderr.write('Connected by %s\\n' % (addr,))\n            # enter network <-> serial loop\n            r = Redirector(\n                ser,\n                connection,\n                options.convert and ser_newline or None,\n                options.convert and net_newline or None,\n                options.spy,\n            )\n            r.shortcut()\n            if options.spy: sys.stdout.write('\\n')\n            sys.stderr.write('Disconnected\\n')\n            connection.close()\n        except KeyboardInterrupt:\n            break\n        except socket.error, msg:\n            sys.stderr.write('ERROR: %s\\n' % msg)\n\n    sys.stderr.write('\\n--- exit ---\\n')\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/wxSerialConfigDialog.py",
    "content": "#!/usr/bin/env python\n# generated by wxGlade 0.3.1 on Thu Oct 02 23:25:44 2003\n\n#from wxPython.wx import *\nimport wx\nimport serial\n\nSHOW_BAUDRATE   = 1<<0\nSHOW_FORMAT     = 1<<1\nSHOW_FLOW       = 1<<2\nSHOW_TIMEOUT    = 1<<3\nSHOW_ALL = SHOW_BAUDRATE|SHOW_FORMAT|SHOW_FLOW|SHOW_TIMEOUT\n\ntry:\n    enumerate\nexcept NameError:\n    def enumerate(sequence):\n        return zip(range(len(sequence)), sequence)\n\nclass SerialConfigDialog(wx.Dialog):\n    \"\"\"Serial Port confiuration dialog, to be used with pyserial 2.0+\n       When instantiating a class of this dialog, then the \"serial\" keyword\n       argument is mandatory. It is a reference to a serial.Serial instance.\n       the optional \"show\" keyword argument can be used to show/hide different\n       settings. The default is SHOW_ALL which coresponds to \n       SHOW_BAUDRATE|SHOW_FORMAT|SHOW_FLOW|SHOW_TIMEOUT. All constants can be\n       found in ths module (not the class).\"\"\"\n    \n    def __init__(self, *args, **kwds):\n        #grab the serial keyword and remove it from the dict\n        self.serial = kwds['serial']\n        del kwds['serial']\n        self.show = SHOW_ALL\n        if kwds.has_key('show'):\n            self.show = kwds['show']\n            del kwds['show']\n        # begin wxGlade: SerialConfigDialog.__init__\n        # end wxGlade\n        kwds[\"style\"] = wx.DEFAULT_DIALOG_STYLE\n        wx.Dialog.__init__(self, *args, **kwds)\n        self.label_2 = wx.StaticText(self, -1, \"Port\")\n        self.combo_box_port = wx.ComboBox(self, -1, choices=[\"dummy1\", \"dummy2\", \"dummy3\", \"dummy4\", \"dummy5\"], style=wx.CB_DROPDOWN)\n        if self.show & SHOW_BAUDRATE:\n            self.label_1 = wx.StaticText(self, -1, \"Baudrate\")\n            self.choice_baudrate = wx.Choice(self, -1, choices=[\"choice 1\"])\n        if self.show & SHOW_FORMAT:\n            self.label_3 = wx.StaticText(self, -1, \"Data Bits\")\n            self.choice_databits = wx.Choice(self, -1, choices=[\"choice 1\"])\n            self.label_4 = wx.StaticText(self, -1, \"Stop Bits\")\n            self.choice_stopbits = wx.Choice(self, -1, choices=[\"choice 1\"])\n            self.label_5 = wx.StaticText(self, -1, \"Parity\")\n            self.choice_parity = wx.Choice(self, -1, choices=[\"choice 1\"])\n        if self.show & SHOW_TIMEOUT:\n            self.checkbox_timeout = wx.CheckBox(self, -1, \"Use Timeout\")\n            self.text_ctrl_timeout = wx.TextCtrl(self, -1, \"\")\n            self.label_6 = wx.StaticText(self, -1, \"seconds\")\n        if self.show & SHOW_FLOW:\n            self.checkbox_rtscts = wx.CheckBox(self, -1, \"RTS/CTS\")\n            self.checkbox_xonxoff = wx.CheckBox(self, -1, \"Xon/Xoff\")\n        self.button_ok = wx.Button(self, -1, \"OK\")\n        self.button_cancel = wx.Button(self, -1, \"Cancel\")\n\n        self.__set_properties()\n        self.__do_layout()\n        #fill in ports and select current setting\n        index = 0\n        self.combo_box_port.Clear()\n        for n in range(4):\n            portname = serial.device(n)\n            self.combo_box_port.Append(portname)\n            if self.serial.portstr == portname:\n                index = n\n        if self.serial.portstr is not None:\n            self.combo_box_port.SetValue(str(self.serial.portstr))\n        else:\n            self.combo_box_port.SetSelection(index)\n        if self.show & SHOW_BAUDRATE:\n            #fill in badrates and select current setting\n            self.choice_baudrate.Clear()\n            for n, baudrate in enumerate(self.serial.BAUDRATES):\n                self.choice_baudrate.Append(str(baudrate))\n                if self.serial.baudrate == baudrate:\n                    index = n\n            self.choice_baudrate.SetSelection(index)\n        if self.show & SHOW_FORMAT:\n            #fill in databits and select current setting\n            self.choice_databits.Clear()\n            for n, bytesize in enumerate(self.serial.BYTESIZES):\n                self.choice_databits.Append(str(bytesize))\n                if self.serial.bytesize == bytesize:\n                    index = n\n            self.choice_databits.SetSelection(index)\n            #fill in stopbits and select current setting\n            self.choice_stopbits.Clear()\n            for n, stopbits in enumerate(self.serial.STOPBITS):\n                self.choice_stopbits.Append(str(stopbits))\n                if self.serial.stopbits == stopbits:\n                    index = n\n            self.choice_stopbits.SetSelection(index)\n            #fill in parities and select current setting\n            self.choice_parity.Clear()\n            for n, parity in enumerate(self.serial.PARITIES):\n                self.choice_parity.Append(str(serial.PARITY_NAMES[parity]))\n                if self.serial.parity == parity:\n                    index = n\n            self.choice_parity.SetSelection(index)\n        if self.show & SHOW_TIMEOUT:\n            #set the timeout mode and value\n            if self.serial.timeout is None:\n                self.checkbox_timeout.SetValue(False)\n                self.text_ctrl_timeout.Enable(False)\n            else:\n                self.checkbox_timeout.SetValue(True)\n                self.text_ctrl_timeout.Enable(True)\n                self.text_ctrl_timeout.SetValue(str(self.serial.timeout))\n        if self.show & SHOW_FLOW:\n            #set the rtscts mode\n            self.checkbox_rtscts.SetValue(self.serial.rtscts)\n            #set the rtscts mode\n            self.checkbox_xonxoff.SetValue(self.serial.xonxoff)\n        #attach the event handlers\n        self.__attach_events()\n\n    def __set_properties(self):\n        # begin wxGlade: SerialConfigDialog.__set_properties\n        # end wxGlade\n        self.SetTitle(\"Serial Port Configuration\")\n        if self.show & SHOW_TIMEOUT:\n            self.text_ctrl_timeout.Enable(0)\n        self.button_ok.SetDefault()\n\n    def __do_layout(self):\n        # begin wxGlade: SerialConfigDialog.__do_layout\n        # end wxGlade\n        sizer_2 = wx.BoxSizer(wx.VERTICAL)\n        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)\n        sizer_basics = wx.StaticBoxSizer(wx.StaticBox(self, -1, \"Basics\"), wx.VERTICAL)\n        sizer_5 = wx.BoxSizer(wx.HORIZONTAL)\n        sizer_5.Add(self.label_2, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)\n        sizer_5.Add(self.combo_box_port, 1, 0, 0)\n        sizer_basics.Add(sizer_5, 0, wx.RIGHT|wx.EXPAND, 0)\n        if self.show & SHOW_BAUDRATE:\n            sizer_baudrate = wx.BoxSizer(wx.HORIZONTAL)\n            sizer_baudrate.Add(self.label_1, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)\n            sizer_baudrate.Add(self.choice_baudrate, 1, wx.ALIGN_RIGHT, 0)\n            sizer_basics.Add(sizer_baudrate, 0, wx.EXPAND, 0)\n        sizer_2.Add(sizer_basics, 0, wx.EXPAND, 0)\n        if self.show & SHOW_FORMAT:\n            sizer_8 = wx.BoxSizer(wx.HORIZONTAL)\n            sizer_7 = wx.BoxSizer(wx.HORIZONTAL)\n            sizer_6 = wx.BoxSizer(wx.HORIZONTAL)\n            sizer_format = wx.StaticBoxSizer(wx.StaticBox(self, -1, \"Data Format\"), wx.VERTICAL)\n            sizer_6.Add(self.label_3, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)\n            sizer_6.Add(self.choice_databits, 1, wx.ALIGN_RIGHT, 0)\n            sizer_format.Add(sizer_6, 0, wx.EXPAND, 0)\n            sizer_7.Add(self.label_4, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)\n            sizer_7.Add(self.choice_stopbits, 1, wx.ALIGN_RIGHT, 0)\n            sizer_format.Add(sizer_7, 0, wx.EXPAND, 0)\n            sizer_8.Add(self.label_5, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)\n            sizer_8.Add(self.choice_parity, 1, wx.ALIGN_RIGHT, 0)\n            sizer_format.Add(sizer_8, 0, wx.EXPAND, 0)\n            sizer_2.Add(sizer_format, 0, wx.EXPAND, 0)\n        if self.show & SHOW_TIMEOUT:\n            sizer_timeout = wx.StaticBoxSizer(wx.StaticBox(self, -1, \"Timeout\"), wx.HORIZONTAL)\n            sizer_timeout.Add(self.checkbox_timeout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)\n            sizer_timeout.Add(self.text_ctrl_timeout, 0, 0, 0)\n            sizer_timeout.Add(self.label_6, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)\n            sizer_2.Add(sizer_timeout, 0, 0, 0)\n        if self.show & SHOW_FLOW:\n            sizer_flow = wx.StaticBoxSizer(wx.StaticBox(self, -1, \"Flow Control\"), wx.HORIZONTAL)\n            sizer_flow.Add(self.checkbox_rtscts, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)\n            sizer_flow.Add(self.checkbox_xonxoff, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)\n            sizer_flow.Add((10,10), 1, wx.EXPAND, 0)\n            sizer_2.Add(sizer_flow, 0, wx.EXPAND, 0)\n        sizer_3.Add(self.button_ok, 0, 0, 0)\n        sizer_3.Add(self.button_cancel, 0, 0, 0)\n        sizer_2.Add(sizer_3, 0, wx.ALL|wx.ALIGN_RIGHT, 4)\n        self.SetAutoLayout(1)\n        self.SetSizer(sizer_2)\n        sizer_2.Fit(self)\n        sizer_2.SetSizeHints(self)\n        self.Layout()\n\n    def __attach_events(self):\n        wx.EVT_BUTTON(self, self.button_ok.GetId(), self.OnOK)\n        wx.EVT_BUTTON(self, self.button_cancel.GetId(), self.OnCancel)\n        if self.show & SHOW_TIMEOUT:\n            wx.EVT_CHECKBOX(self, self.checkbox_timeout.GetId(), self.OnTimeout)\n\n    def OnOK(self, events):\n        success = True\n        self.serial.port     = str(self.combo_box_port.GetValue())\n        if self.show & SHOW_BAUDRATE:\n            self.serial.baudrate = self.serial.BAUDRATES[self.choice_baudrate.GetSelection()]\n        if self.show & SHOW_FORMAT:\n            self.serial.bytesize = self.serial.BYTESIZES[self.choice_databits.GetSelection()]\n            self.serial.stopbits = self.serial.STOPBITS[self.choice_stopbits.GetSelection()]\n            self.serial.parity   = self.serial.PARITIES[self.choice_parity.GetSelection()]\n        if self.show & SHOW_FLOW:\n            self.serial.rtscts   = self.checkbox_rtscts.GetValue()\n            self.serial.xonxoff  = self.checkbox_xonxoff.GetValue()\n        if self.show & SHOW_TIMEOUT:\n            if self.checkbox_timeout.GetValue():\n                try:\n                    self.serial.timeout = float(self.text_ctrl_timeout.GetValue())\n                except ValueError:\n                    dlg = wx.MessageDialog(self, 'Timeout must be a numeric value',\n                                                'Value Error', wx.OK | wx.ICON_ERROR)\n                    dlg.ShowModal()\n                    dlg.Destroy()\n                    success = False\n            else:\n                self.serial.timeout = None\n        if success:\n            self.EndModal(wx.ID_OK)\n\n    def OnCancel(self, events):\n        self.EndModal(wx.ID_CANCEL)\n\n    def OnTimeout(self, events):\n        if self.checkbox_timeout.GetValue():\n            self.text_ctrl_timeout.Enable(True)\n        else:\n            self.text_ctrl_timeout.Enable(False)\n\n# end of class SerialConfigDialog\n\n\nclass MyApp(wx.App):\n    \"\"\"Test code\"\"\"\n    def OnInit(self):\n        wx.InitAllImageHandlers()\n        \n        ser = serial.Serial()\n        print ser\n        #loop until cancel is pressed, old values are used as start for the next run\n        #show the different views, one after the other\n        #value are kept.\n        for flags in (SHOW_BAUDRATE, SHOW_FLOW, SHOW_FORMAT, SHOW_TIMEOUT, SHOW_ALL):\n            dialog_serial_cfg = SerialConfigDialog(None, -1, \"\", serial=ser, show=flags)\n            self.SetTopWindow(dialog_serial_cfg)\n            result = dialog_serial_cfg.ShowModal()\n            print ser\n            if result != wx.ID_OK:\n                break\n        #the user can play around with the values, CANCEL aborts the loop\n        while 1:\n            dialog_serial_cfg = SerialConfigDialog(None, -1, \"\", serial=ser)\n            self.SetTopWindow(dialog_serial_cfg)\n            result = dialog_serial_cfg.ShowModal()\n            print ser\n            if result != wx.ID_OK:\n                break\n        return 0\n\n# end of class MyApp\n\nif __name__ == \"__main__\":\n    app = MyApp(0)\n    app.MainLoop()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/wxSerialConfigDialog.wxg",
    "content": "<?xml version=\"1.0\"?>\n<!-- generated by wxGlade 0.3.1 on Fri Oct 03 01:53:04 2003 -->\n\n<application path=\"D:\\prog\\python\\pyserial_sf\\pyserial\\examples\\wxSerialConfigDialog.py\" name=\"app\" class=\"MyApp\" option=\"0\" language=\"python\" top_window=\"dialog_serial_cfg\" encoding=\"ISO-8859-1\" use_gettext=\"0\" overwrite=\"0\">\n    <object class=\"SerialConfigDialog\" name=\"dialog_serial_cfg\" base=\"EditDialog\">\n        <style>wxDEFAULT_DIALOG_STYLE</style>\n        <title>Serial Port Configuration</title>\n        <object class=\"wxBoxSizer\" name=\"sizer_2\" base=\"EditBoxSizer\">\n            <orient>wxVERTICAL</orient>\n            <object class=\"sizeritem\">\n                <flag>wxEXPAND</flag>\n                <border>0</border>\n                <option>0</option>\n                <object class=\"wxStaticBoxSizer\" name=\"sizer_basics\" base=\"EditStaticBoxSizer\">\n                    <orient>wxVERTICAL</orient>\n                    <label>Basics</label>\n                    <object class=\"sizeritem\">\n                        <flag>wxRIGHT|wxEXPAND</flag>\n                        <border>0</border>\n                        <option>0</option>\n                        <object class=\"wxBoxSizer\" name=\"sizer_5\" base=\"EditBoxSizer\">\n                            <orient>wxHORIZONTAL</orient>\n                            <object class=\"sizeritem\">\n                                <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>\n                                <border>4</border>\n                                <option>1</option>\n                                <object class=\"wxStaticText\" name=\"label_2\" base=\"EditStaticText\">\n                                    <attribute>1</attribute>\n                                    <label>Port</label>\n                                </object>\n                            </object>\n                            <object class=\"sizeritem\">\n                                <border>0</border>\n                                <option>1</option>\n                                <object class=\"wxComboBox\" name=\"combo_box_port\" base=\"EditComboBox\">\n                                    <selection>0</selection>\n                                    <choices>\n                                        <choice>dummy1</choice>\n                                        <choice>dummy2</choice>\n                                        <choice>dummy3</choice>\n                                        <choice>dummy4</choice>\n                                        <choice>dummy5</choice>\n                                    </choices>\n                                </object>\n                            </object>\n                        </object>\n                    </object>\n                    <object class=\"sizeritem\">\n                        <flag>wxEXPAND</flag>\n                        <border>0</border>\n                        <option>0</option>\n                        <object class=\"wxBoxSizer\" name=\"sizer_baudrate\" base=\"EditBoxSizer\">\n                            <orient>wxHORIZONTAL</orient>\n                            <object class=\"sizeritem\">\n                                <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>\n                                <border>4</border>\n                                <option>1</option>\n                                <object class=\"wxStaticText\" name=\"label_1\" base=\"EditStaticText\">\n                                    <attribute>1</attribute>\n                                    <label>Baudrate</label>\n                                </object>\n                            </object>\n                            <object class=\"sizeritem\">\n                                <flag>wxALIGN_RIGHT</flag>\n                                <border>0</border>\n                                <option>1</option>\n                                <object class=\"wxChoice\" name=\"choice_baudrate\" base=\"EditChoice\">\n                                    <selection>0</selection>\n                                    <choices>\n                                        <choice>choice 1</choice>\n                                    </choices>\n                                </object>\n                            </object>\n                        </object>\n                    </object>\n                </object>\n            </object>\n            <object class=\"sizeritem\">\n                <flag>wxEXPAND</flag>\n                <border>0</border>\n                <option>0</option>\n                <object class=\"wxStaticBoxSizer\" name=\"sizer_format\" base=\"EditStaticBoxSizer\">\n                    <orient>wxVERTICAL</orient>\n                    <label>Data Format</label>\n                    <object class=\"sizeritem\">\n                        <flag>wxEXPAND</flag>\n                        <border>0</border>\n                        <option>0</option>\n                        <object class=\"wxBoxSizer\" name=\"sizer_6\" base=\"EditBoxSizer\">\n                            <orient>wxHORIZONTAL</orient>\n                            <object class=\"sizeritem\">\n                                <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>\n                                <border>4</border>\n                                <option>1</option>\n                                <object class=\"wxStaticText\" name=\"label_3\" base=\"EditStaticText\">\n                                    <attribute>1</attribute>\n                                    <label>Data Bits</label>\n                                </object>\n                            </object>\n                            <object class=\"sizeritem\">\n                                <flag>wxALIGN_RIGHT</flag>\n                                <border>0</border>\n                                <option>1</option>\n                                <object class=\"wxChoice\" name=\"choice_databits\" base=\"EditChoice\">\n                                    <selection>0</selection>\n                                    <choices>\n                                        <choice>choice 1</choice>\n                                    </choices>\n                                </object>\n                            </object>\n                        </object>\n                    </object>\n                    <object class=\"sizeritem\">\n                        <flag>wxEXPAND</flag>\n                        <border>0</border>\n                        <option>0</option>\n                        <object class=\"wxBoxSizer\" name=\"sizer_7\" base=\"EditBoxSizer\">\n                            <orient>wxHORIZONTAL</orient>\n                            <object class=\"sizeritem\">\n                                <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>\n                                <border>4</border>\n                                <option>1</option>\n                                <object class=\"wxStaticText\" name=\"label_4\" base=\"EditStaticText\">\n                                    <attribute>1</attribute>\n                                    <label>Stop Bits</label>\n                                </object>\n                            </object>\n                            <object class=\"sizeritem\">\n                                <flag>wxALIGN_RIGHT</flag>\n                                <border>0</border>\n                                <option>1</option>\n                                <object class=\"wxChoice\" name=\"choice_stopbits\" base=\"EditChoice\">\n                                    <selection>0</selection>\n                                    <choices>\n                                        <choice>choice 1</choice>\n                                    </choices>\n                                </object>\n                            </object>\n                        </object>\n                    </object>\n                    <object class=\"sizeritem\">\n                        <flag>wxEXPAND</flag>\n                        <border>0</border>\n                        <option>0</option>\n                        <object class=\"wxBoxSizer\" name=\"sizer_8\" base=\"EditBoxSizer\">\n                            <orient>wxHORIZONTAL</orient>\n                            <object class=\"sizeritem\">\n                                <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>\n                                <border>4</border>\n                                <option>1</option>\n                                <object class=\"wxStaticText\" name=\"label_5\" base=\"EditStaticText\">\n                                    <attribute>1</attribute>\n                                    <label>Parity</label>\n                                </object>\n                            </object>\n                            <object class=\"sizeritem\">\n                                <flag>wxALIGN_RIGHT</flag>\n                                <border>0</border>\n                                <option>1</option>\n                                <object class=\"wxChoice\" name=\"choice_parity\" base=\"EditChoice\">\n                                    <selection>0</selection>\n                                    <choices>\n                                        <choice>choice 1</choice>\n                                    </choices>\n                                </object>\n                            </object>\n                        </object>\n                    </object>\n                </object>\n            </object>\n            <object class=\"sizeritem\">\n                <border>0</border>\n                <option>0</option>\n                <object class=\"wxStaticBoxSizer\" name=\"sizer_timeout\" base=\"EditStaticBoxSizer\">\n                    <orient>wxHORIZONTAL</orient>\n                    <label>Timeout</label>\n                    <object class=\"sizeritem\">\n                        <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>\n                        <border>4</border>\n                        <option>0</option>\n                        <object class=\"wxCheckBox\" name=\"checkbox_timeout\" base=\"EditCheckBox\">\n                            <label>Use Timeout</label>\n                        </object>\n                    </object>\n                    <object class=\"sizeritem\">\n                        <border>0</border>\n                        <option>0</option>\n                        <object class=\"wxTextCtrl\" name=\"text_ctrl_timeout\" base=\"EditTextCtrl\">\n                            <disabled>1</disabled>\n                        </object>\n                    </object>\n                    <object class=\"sizeritem\">\n                        <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>\n                        <border>4</border>\n                        <option>0</option>\n                        <object class=\"wxStaticText\" name=\"label_6\" base=\"EditStaticText\">\n                            <attribute>1</attribute>\n                            <label>seconds</label>\n                        </object>\n                    </object>\n                </object>\n            </object>\n            <object class=\"sizeritem\">\n                <flag>wxEXPAND</flag>\n                <border>0</border>\n                <option>0</option>\n                <object class=\"wxStaticBoxSizer\" name=\"sizer_flow\" base=\"EditStaticBoxSizer\">\n                    <orient>wxHORIZONTAL</orient>\n                    <label>Flow Control</label>\n                    <object class=\"sizeritem\">\n                        <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>\n                        <border>4</border>\n                        <option>0</option>\n                        <object class=\"wxCheckBox\" name=\"checkbox_rtscts\" base=\"EditCheckBox\">\n                            <label>RTS/CTS</label>\n                        </object>\n                    </object>\n                    <object class=\"sizeritem\">\n                        <flag>wxALL|wxALIGN_CENTER_VERTICAL</flag>\n                        <border>4</border>\n                        <option>0</option>\n                        <object class=\"wxCheckBox\" name=\"checkbox_xonxoff\" base=\"EditCheckBox\">\n                            <label>Xon/Xoff</label>\n                        </object>\n                    </object>\n                    <object class=\"sizeritem\">\n                        <flag>wxEXPAND</flag>\n                        <border>0</border>\n                        <option>1</option>\n                        <object class=\"spacer\" name=\"spacer\" base=\"EditSpacer\">\n                            <height>10</height>\n                            <width>10</width>\n                        </object>\n                    </object>\n                </object>\n            </object>\n            <object class=\"sizeritem\">\n                <flag>wxALL|wxALIGN_RIGHT</flag>\n                <border>4</border>\n                <option>0</option>\n                <object class=\"wxBoxSizer\" name=\"sizer_3\" base=\"EditBoxSizer\">\n                    <orient>wxHORIZONTAL</orient>\n                    <object class=\"sizeritem\">\n                        <border>0</border>\n                        <option>0</option>\n                        <object class=\"wxButton\" name=\"button_ok\" base=\"EditButton\">\n                            <default>1</default>\n                            <label>OK</label>\n                        </object>\n                    </object>\n                    <object class=\"sizeritem\">\n                        <border>0</border>\n                        <option>0</option>\n                        <object class=\"wxButton\" name=\"button_cancel\" base=\"EditButton\">\n                            <label>Cancel</label>\n                        </object>\n                    </object>\n                </object>\n            </object>\n        </object>\n    </object>\n</application>\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/wxTerminal.py",
    "content": "#!/usr/bin/env python\n# generated by wxGlade 0.3.1 on Fri Oct 03 23:23:45 2003\n\n#from wxPython.wx import *\nimport wx\nimport wxSerialConfigDialog\nimport serial\nimport threading\n\n#----------------------------------------------------------------------\n# Create an own event type, so that GUI updates can be delegated\n# this is required as on some platforms only the main thread can\n# access the GUI without crashing. wxMutexGuiEnter/wxMutexGuiLeave\n# could be used too, but an event is more elegant.\n\nSERIALRX = wx.NewEventType()\n# bind to serial data receive events\nEVT_SERIALRX = wx.PyEventBinder(SERIALRX, 0)\n\nclass SerialRxEvent(wx.PyCommandEvent):\n    eventType = SERIALRX\n    def __init__(self, windowID, data):\n        wx.PyCommandEvent.__init__(self, self.eventType, windowID)\n        self.data = data\n\n    def Clone(self):\n        self.__class__(self.GetId(), self.data)\n\n#----------------------------------------------------------------------\n\nID_CLEAR        = wx.NewId()\nID_SAVEAS       = wx.NewId()\nID_SETTINGS     = wx.NewId()\nID_TERM         = wx.NewId()\nID_EXIT         = wx.NewId()\n\nNEWLINE_CR      = 0\nNEWLINE_LF      = 1\nNEWLINE_CRLF    = 2\n\nclass TerminalSetup:\n    \"\"\"Placeholder for various terminal settings. Used to pass the\n       options to the TerminalSettingsDialog.\"\"\"\n    def __init__(self):\n        self.echo = False\n        self.unprintable = False\n        self.newline = NEWLINE_CRLF\n\nclass TerminalSettingsDialog(wx.Dialog):\n    \"\"\"Simple dialog with common terminal settings like echo, newline mode.\"\"\"\n    \n    def __init__(self, *args, **kwds):\n        self.settings = kwds['settings']\n        del kwds['settings']\n        # begin wxGlade: TerminalSettingsDialog.__init__\n        kwds[\"style\"] = wx.DEFAULT_DIALOG_STYLE\n        wx.Dialog.__init__(self, *args, **kwds)\n        self.checkbox_echo = wx.CheckBox(self, -1, \"Local Echo\")\n        self.checkbox_unprintable = wx.CheckBox(self, -1, \"Show unprintable characters\")\n        self.radio_box_newline = wx.RadioBox(self, -1, \"Newline Handling\", choices=[\"CR only\", \"LF only\", \"CR+LF\"], majorDimension=0, style=wx.RA_SPECIFY_ROWS)\n        self.button_ok = wx.Button(self, -1, \"OK\")\n        self.button_cancel = wx.Button(self, -1, \"Cancel\")\n\n        self.__set_properties()\n        self.__do_layout()\n        # end wxGlade\n        self.__attach_events()\n        self.checkbox_echo.SetValue(self.settings.echo)\n        self.checkbox_unprintable.SetValue(self.settings.unprintable)\n        self.radio_box_newline.SetSelection(self.settings.newline)\n\n    def __set_properties(self):\n        # begin wxGlade: TerminalSettingsDialog.__set_properties\n        self.SetTitle(\"Terminal Settings\")\n        self.radio_box_newline.SetSelection(0)\n        self.button_ok.SetDefault()\n        # end wxGlade\n\n    def __do_layout(self):\n        # begin wxGlade: TerminalSettingsDialog.__do_layout\n        sizer_2 = wx.BoxSizer(wx.VERTICAL)\n        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)\n        sizer_4 = wx.StaticBoxSizer(wx.StaticBox(self, -1, \"Input/Output\"), wx.VERTICAL)\n        sizer_4.Add(self.checkbox_echo, 0, wx.ALL, 4)\n        sizer_4.Add(self.checkbox_unprintable, 0, wx.ALL, 4)\n        sizer_4.Add(self.radio_box_newline, 0, 0, 0)\n        sizer_2.Add(sizer_4, 0, wx.EXPAND, 0)\n        sizer_3.Add(self.button_ok, 0, 0, 0)\n        sizer_3.Add(self.button_cancel, 0, 0, 0)\n        sizer_2.Add(sizer_3, 0, wx.ALL|wx.ALIGN_RIGHT, 4)\n        self.SetAutoLayout(1)\n        self.SetSizer(sizer_2)\n        sizer_2.Fit(self)\n        sizer_2.SetSizeHints(self)\n        self.Layout()\n        # end wxGlade\n\n    def __attach_events(self):\n        self.Bind(wx.EVT_BUTTON, self.OnOK, id = self.button_ok.GetId())\n        self.Bind(wx.EVT_BUTTON, self.OnCancel, id = self.button_cancel.GetId())\n    \n    def OnOK(self, events):\n        \"\"\"Update data wil new values and close dialog.\"\"\"\n        self.settings.echo = self.checkbox_echo.GetValue()\n        self.settings.unprintable = self.checkbox_unprintable.GetValue()\n        self.settings.newline = self.radio_box_newline.GetSelection()\n        self.EndModal(wx.ID_OK)\n    \n    def OnCancel(self, events):\n        \"\"\"Do not update data but close dialog.\"\"\"\n        self.EndModal(wx.ID_CANCEL)\n\n# end of class TerminalSettingsDialog\n\n\nclass TerminalFrame(wx.Frame):\n    \"\"\"Simple terminal program for wxPython\"\"\"\n    \n    def __init__(self, *args, **kwds):\n        self.serial = serial.Serial()\n        self.serial.timeout = 0.5   #make sure that the alive event can be checked from time to time\n        self.settings = TerminalSetup() #placeholder for the settings\n        self.thread = None\n        self.alive = threading.Event()               \n        # begin wxGlade: TerminalFrame.__init__\n        kwds[\"style\"] = wx.DEFAULT_FRAME_STYLE\n        wx.Frame.__init__(self, *args, **kwds)\n        self.text_ctrl_output = wx.TextCtrl(self, -1, \"\", style=wx.TE_MULTILINE|wx.TE_READONLY)\n        \n        # Menu Bar\n        self.frame_terminal_menubar = wx.MenuBar()\n        self.SetMenuBar(self.frame_terminal_menubar)\n        wxglade_tmp_menu = wx.Menu()\n        wxglade_tmp_menu.Append(ID_CLEAR, \"&Clear\", \"\", wx.ITEM_NORMAL)\n        wxglade_tmp_menu.Append(ID_SAVEAS, \"&Save Text As...\", \"\", wx.ITEM_NORMAL)\n        wxglade_tmp_menu.AppendSeparator()\n        wxglade_tmp_menu.Append(ID_SETTINGS, \"&Port Settings...\", \"\", wx.ITEM_NORMAL)\n        wxglade_tmp_menu.Append(ID_TERM, \"&Terminal Settings...\", \"\", wx.ITEM_NORMAL)\n        wxglade_tmp_menu.AppendSeparator()\n        wxglade_tmp_menu.Append(ID_EXIT, \"&Exit\", \"\", wx.ITEM_NORMAL)\n        self.frame_terminal_menubar.Append(wxglade_tmp_menu, \"&File\")\n        # Menu Bar end\n\n        self.__set_properties()\n        self.__do_layout()\n        # end wxGlade\n        self.__attach_events()          #register events\n        self.OnPortSettings(None)       #call setup dialog on startup, opens port\n        if not self.alive.isSet():\n            self.Close()\n\n    def StartThread(self):\n        \"\"\"Start the receiver thread\"\"\"        \n        self.thread = threading.Thread(target=self.ComPortThread)\n        self.thread.setDaemon(1)\n        self.alive.set()\n        self.thread.start()\n\n    def StopThread(self):\n        \"\"\"Stop the receiver thread, wait util it's finished.\"\"\"\n        if self.thread is not None:\n            self.alive.clear()          #clear alive event for thread\n            self.thread.join()          #wait until thread has finished\n            self.thread = None\n        \n    def __set_properties(self):\n        # begin wxGlade: TerminalFrame.__set_properties\n        self.SetTitle(\"Serial Terminal\")\n        self.SetSize((546, 383))\n        # end wxGlade\n\n    def __do_layout(self):\n        # begin wxGlade: TerminalFrame.__do_layout\n        sizer_1 = wx.BoxSizer(wx.VERTICAL)\n        sizer_1.Add(self.text_ctrl_output, 1, wx.EXPAND, 0)\n        self.SetAutoLayout(1)\n        self.SetSizer(sizer_1)\n        self.Layout()\n        # end wxGlade\n\n    def __attach_events(self):\n        #register events at the controls\n        self.Bind(wx.EVT_MENU, self.OnClear, id = ID_CLEAR)\n        self.Bind(wx.EVT_MENU, self.OnSaveAs, id = ID_SAVEAS)\n        self.Bind(wx.EVT_MENU, self.OnExit, id = ID_EXIT)\n        self.Bind(wx.EVT_MENU, self.OnPortSettings, id = ID_SETTINGS)\n        self.Bind(wx.EVT_MENU, self.OnTermSettings, id = ID_TERM)\n        self.text_ctrl_output.Bind(wx.EVT_CHAR, self.OnKey)        \n        self.Bind(EVT_SERIALRX, self.OnSerialRead)\n        self.Bind(wx.EVT_CLOSE, self.OnClose)\n\n    def OnExit(self, event):\n        \"\"\"Menu point Exit\"\"\"\n        self.Close()\n\n    def OnClose(self, event):\n        \"\"\"Called on application shutdown.\"\"\"\n        self.StopThread()               #stop reader thread\n        self.serial.close()             #cleanup\n        self.Destroy()                  #close windows, exit app\n\n    def OnSaveAs(self, event):\n        \"\"\"Save contents of output window.\"\"\"\n        filename = None\n        dlg = wx.FileDialog(None, \"Save Text As...\", \".\", \"\", \"Text File|*.txt|All Files|*\",  wx.SAVE)\n        if dlg.ShowModal() ==  wx.ID_OK:\n            filename = dlg.GetPath()\n        dlg.Destroy()\n        \n        if filename is not None:\n            f = file(filename, 'w')\n            text = self.text_ctrl_output.GetValue()\n            if type(text) == unicode:\n                text = text.encode(\"latin1\")    #hm, is that a good asumption?\n            f.write(text)\n            f.close()\n    \n    def OnClear(self, event):\n        \"\"\"Clear contents of output window.\"\"\"\n        self.text_ctrl_output.Clear()\n    \n    def OnPortSettings(self, event=None):\n        \"\"\"Show the portsettings dialog. The reader thread is stopped for the\n           settings change.\"\"\"\n        if event is not None:           #will be none when called on startup\n            self.StopThread()\n            self.serial.close()\n        ok = False\n        while not ok:\n            dialog_serial_cfg = wxSerialConfigDialog.SerialConfigDialog(None, -1, \"\",\n                show=wxSerialConfigDialog.SHOW_BAUDRATE|wxSerialConfigDialog.SHOW_FORMAT|wxSerialConfigDialog.SHOW_FLOW,\n                serial=self.serial\n            )\n            result = dialog_serial_cfg.ShowModal()\n            dialog_serial_cfg.Destroy()\n            #open port if not called on startup, open it on startup and OK too\n            if result == wx.ID_OK or event is not None:\n                try:\n                    self.serial.open()\n                except serial.SerialException, e:\n                    dlg = wx.MessageDialog(None, str(e), \"Serial Port Error\", wx.OK | wx.ICON_ERROR)\n                    dlg.ShowModal()\n                    dlg.Destroy()\n                else:\n                    self.StartThread()\n                    self.SetTitle(\"Serial Terminal on %s [%s, %s%s%s%s%s]\" % (\n                        self.serial.portstr,\n                        self.serial.baudrate,\n                        self.serial.bytesize,\n                        self.serial.parity,\n                        self.serial.stopbits,\n                        self.serial.rtscts and ' RTS/CTS' or '',\n                        self.serial.xonxoff and ' Xon/Xoff' or '',\n                        )\n                    )\n                    ok = True\n            else:\n                #on startup, dialog aborted\n                self.alive.clear()\n                ok = True\n\n    def OnTermSettings(self, event):\n        \"\"\"Menu point Terminal Settings. Show the settings dialog\n           with the current terminal settings\"\"\"\n        dialog = TerminalSettingsDialog(None, -1, \"\", settings=self.settings)\n        result = dialog.ShowModal()\n        dialog.Destroy()\n        \n    def OnKey(self, event):\n        \"\"\"Key event handler. if the key is in the ASCII range, write it to the serial port.\n           Newline handling and local echo is also done here.\"\"\"\n        code = event.GetKeyCode()\n        if code < 256:                          #is it printable?\n            if code == 13:                      #is it a newline? (check for CR which is the RETURN key)\n                if self.settings.echo:          #do echo if needed\n                    self.text_ctrl_output.AppendText('\\n')\n                if self.settings.newline == NEWLINE_CR:\n                    self.serial.write('\\r')     #send CR\n                elif self.settings.newline == NEWLINE_LF:\n                    self.serial.write('\\n')     #send LF\n                elif self.settings.newline == NEWLINE_CRLF:\n                    self.serial.write('\\r\\n')   #send CR+LF\n            else:\n                char = chr(code)\n                if self.settings.echo:          #do echo if needed\n                    self.text_ctrl_output.WriteText(char)\n                self.serial.write(char)         #send the charcater\n        else:\n            print \"Extra Key:\", code\n\n    def OnSerialRead(self, event):\n        \"\"\"Handle input from the serial port.\"\"\"\n        text = event.data\n        if self.settings.unprintable:\n            text = ''.join([(c >= ' ') and c or '<%d>' % ord(c)  for c in text])\n        self.text_ctrl_output.AppendText(text)\n\n    def ComPortThread(self):\n        \"\"\"Thread that handles the incomming traffic. Does the basic input\n           transformation (newlines) and generates an SerialRxEvent\"\"\"\n        while self.alive.isSet():               #loop while alive event is true\n            text = self.serial.read(1)          #read one, with timout\n            if text:                            #check if not timeout\n                n = self.serial.inWaiting()     #look if there is more to read\n                if n:\n                    text = text + self.serial.read(n) #get it\n                #newline transformation\n                if self.settings.newline == NEWLINE_CR:\n                    text = text.replace('\\r', '\\n')\n                elif self.settings.newline == NEWLINE_LF:\n                    pass\n                elif self.settings.newline == NEWLINE_CRLF:\n                    text = text.replace('\\r\\n', '\\n')\n                event = SerialRxEvent(self.GetId(), text)\n                self.GetEventHandler().AddPendingEvent(event)\n                #~ self.OnSerialRead(text)         #output text in window\n            \n# end of class TerminalFrame\n\n\nclass MyApp(wx.App):\n    def OnInit(self):\n        wx.InitAllImageHandlers()\n        frame_terminal = TerminalFrame(None, -1, \"\")\n        self.SetTopWindow(frame_terminal)\n        frame_terminal.Show(1)\n        return 1\n\n# end of class MyApp\n\nif __name__ == \"__main__\":\n    app = MyApp(0)\n    app.MainLoop()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/examples/wxTerminal.wxg",
    "content": "<?xml version=\"1.0\"?>\n<!-- generated by wxGlade 0.3.1 on Sat Oct 04 02:41:48 2003 -->\n\n<application path=\"D:\\prog\\python\\pyserial_sf\\pyserial\\examples\\wxTerminal.py\" name=\"app\" class=\"MyApp\" option=\"0\" language=\"python\" top_window=\"frame_terminal\" encoding=\"ISO-8859-1\" use_gettext=\"0\" overwrite=\"0\">\n    <object class=\"TerminalFrame\" name=\"frame_terminal\" base=\"EditFrame\">\n        <style>wxDEFAULT_FRAME_STYLE</style>\n        <title>Serial Terminal</title>\n        <menubar>1</menubar>\n        <size>546, 383</size>\n        <object class=\"wxBoxSizer\" name=\"sizer_1\" base=\"EditBoxSizer\">\n            <orient>wxVERTICAL</orient>\n            <object class=\"sizeritem\">\n                <flag>wxEXPAND</flag>\n                <border>0</border>\n                <option>1</option>\n                <object class=\"wxTextCtrl\" name=\"text_ctrl_output\" base=\"EditTextCtrl\">\n                    <style>wxTE_MULTILINE|wxTE_READONLY</style>\n                </object>\n            </object>\n        </object>\n        <object class=\"wxMenuBar\" name=\"frame_terminal_menubar\" base=\"EditMenuBar\">\n            <menus>\n                <menu name=\"\" label=\"&amp;File\">\n                    <item>\n                        <label>&amp;Clear</label>\n                        <id>ID_CLEAR</id>\n                    </item>\n                    <item>\n                        <label>&amp;Save Text As...</label>\n                        <id>ID_SAVEAS</id>\n                    </item>\n                    <item>\n                        <label>---</label>\n                        <id>---</id>\n                        <name>---</name>\n                    </item>\n                    <item>\n                        <label>&amp;Port Settings...</label>\n                        <id>ID_SETTINGS</id>\n                    </item>\n                    <item>\n                        <label>&amp;Terminal Settings...</label>\n                        <id>ID_TERM</id>\n                    </item>\n                    <item>\n                        <label>---</label>\n                        <name>---</name>\n                    </item>\n                    <item>\n                        <label>&amp;Exit</label>\n                        <id>ID_EXIT</id>\n                    </item>\n                </menu>\n            </menus>\n        </object>\n    </object>\n    <object class=\"TerminalSettingsDialog\" name=\"dialog_terminal_Settings\" base=\"EditDialog\">\n        <style>wxDEFAULT_DIALOG_STYLE</style>\n        <title>Terminal Settings</title>\n        <object class=\"wxBoxSizer\" name=\"sizer_2\" base=\"EditBoxSizer\">\n            <orient>wxVERTICAL</orient>\n            <object class=\"sizeritem\">\n                <flag>wxEXPAND</flag>\n                <border>0</border>\n                <option>0</option>\n                <object class=\"wxStaticBoxSizer\" name=\"sizer_4\" base=\"EditStaticBoxSizer\">\n                    <orient>wxVERTICAL</orient>\n                    <label>Input/Output</label>\n                    <object class=\"sizeritem\">\n                        <flag>wxALL</flag>\n                        <border>4</border>\n                        <option>0</option>\n                        <object class=\"wxCheckBox\" name=\"checkbox_echo\" base=\"EditCheckBox\">\n                            <label>Local Echo</label>\n                        </object>\n                    </object>\n                    <object class=\"sizeritem\">\n                        <flag>wxALL</flag>\n                        <border>4</border>\n                        <option>0</option>\n                        <object class=\"wxCheckBox\" name=\"checkbox_unprintable\" base=\"EditCheckBox\">\n                            <label>Show unprintable characters</label>\n                        </object>\n                    </object>\n                    <object class=\"sizeritem\">\n                        <border>0</border>\n                        <option>0</option>\n                        <object class=\"wxRadioBox\" name=\"radio_box_newline\" base=\"EditRadioBox\">\n                            <style>wxRA_SPECIFY_ROWS</style>\n                            <selection>0</selection>\n                            <dimension>0</dimension>\n                            <label>Newline Handling</label>\n                            <choices>\n                                <choice>CR only</choice>\n                                <choice>LF only</choice>\n                                <choice>CR+LF</choice>\n                            </choices>\n                        </object>\n                    </object>\n                </object>\n            </object>\n            <object class=\"sizeritem\">\n                <flag>wxALL|wxALIGN_RIGHT</flag>\n                <border>4</border>\n                <option>0</option>\n                <object class=\"wxBoxSizer\" name=\"sizer_3\" base=\"EditBoxSizer\">\n                    <orient>wxHORIZONTAL</orient>\n                    <object class=\"sizeritem\">\n                        <border>0</border>\n                        <option>0</option>\n                        <object class=\"wxButton\" name=\"button_ok\" base=\"EditButton\">\n                            <default>1</default>\n                            <label>OK</label>\n                        </object>\n                    </object>\n                    <object class=\"sizeritem\">\n                        <border>0</border>\n                        <option>0</option>\n                        <object class=\"wxButton\" name=\"button_cancel\" base=\"EditButton\">\n                            <label>Cancel</label>\n                        </object>\n                    </object>\n                </object>\n            </object>\n        </object>\n    </object>\n</application>\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/__init__.py",
    "content": "#!/usr/bin/env python \n\n# portable serial port access with python\n# this is a wrapper module for different platform implementations\n#\n# (C) 2001-2010 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n\nVERSION = '2.6'\n\nimport sys\n\nif sys.platform == 'cli':\n    from serial.serialcli import *\nelse:\n    import os\n    # chose an implementation, depending on os\n    if os.name == 'nt': #sys.platform == 'win32':\n        from serial.serialwin32 import *\n    elif os.name == 'posix':\n        from serial.serialposix import *\n    elif os.name == 'java':\n        from serial.serialjava import *\n    else:\n        raise ImportError(\"Sorry: no implementation for your platform ('%s') available\" % (os.name,))\n\n\nprotocol_handler_packages = [\n        'serial.urlhandler',\n        ]\n\ndef serial_for_url(url, *args, **kwargs):\n    \"\"\"\\\n    Get an instance of the Serial class, depending on port/url. The port is not\n    opened when the keyword parameter 'do_not_open' is true, by default it\n    is. All other parameters are directly passed to the __init__ method when\n    the port is instantiated.\n\n    The list of package names that is searched for protocol handlers is kept in\n    ``protocol_handler_packages``.\n\n    e.g. we want to support a URL ``foobar://``. A module\n    ``my_handlers.protocol_foobar`` is provided by the user. Then\n    ``protocol_handler_packages.append(\"my_handlers\")`` would extend the search\n    path so that ``serial_for_url(\"foobar://\"))`` would work.\n    \"\"\"\n    # check remove extra parameter to not confuse the Serial class\n    do_open = 'do_not_open' not in kwargs or not kwargs['do_not_open']\n    if 'do_not_open' in kwargs: del kwargs['do_not_open']\n    # the default is to use the native version\n    klass = Serial   # 'native' implementation\n    # check port type and get class\n    try:\n        url_nocase = url.lower()\n    except AttributeError:\n        # it's not a string, use default\n        pass\n    else:\n        if '://' in url_nocase:\n            protocol = url_nocase.split('://', 1)[0]\n            for package_name in protocol_handler_packages:\n                module_name = '%s.protocol_%s' % (package_name, protocol,)\n                try:\n                    handler_module = __import__(module_name)\n                except ImportError:\n                    pass\n                else:\n                    klass = sys.modules[module_name].Serial\n                    break\n            else:\n                raise ValueError('invalid URL, protocol %r not known' % (protocol,))\n        else:\n            klass = Serial   # 'native' implementation\n    # instantiate and open when desired\n    instance = klass(None, *args, **kwargs)\n    instance.port = url\n    if do_open:\n        instance.open()\n    return instance\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/rfc2217.py",
    "content": "#! python\n#\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# see __init__.py\n#\n# This module implements a RFC2217 compatible client. RF2217 descibes a\n# protocol to access serial ports over TCP/IP and allows setting the baud rate,\n# modem control lines etc.\n#\n# (C) 2001-2009 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n\n# TODO:\n# - setting control line -> answer is not checked (had problems with one of the\n#   severs). consider implementing a compatibility mode flag to make check\n#   conditional\n# - write timeout not implemented at all\n\n##############################################################################\n# observations and issues with servers\n#=============================================================================\n# sredird V2.2.1\n# - http://www.ibiblio.org/pub/Linux/system/serial/   sredird-2.2.2.tar.gz\n# - does not acknowledge SET_CONTROL (RTS/DTR) correctly, always responding\n#   [105 1] instead of the actual value.\n# - SET_BAUDRATE answer contains 4 extra null bytes -> probably for larger\n#   numbers than 2**32?\n# - To get the signature [COM_PORT_OPTION 0] has to be sent.\n# - run a server: while true; do nc -l -p 7000 -c \"sredird debug /dev/ttyUSB0 /var/lock/sredir\"; done\n#=============================================================================\n# telnetcpcd (untested)\n# - http://ftp.wayne.edu/kermit/sredird/telnetcpcd-1.09.tar.gz\n# - To get the signature [COM_PORT_OPTION] w/o data has to be sent.\n#=============================================================================\n# ser2net\n# - does not negotiate BINARY or COM_PORT_OPTION for his side but at least\n#   acknowledges that the client activates these options\n# - The configuration may be that the server prints a banner. As this client\n#   implementation does a flushInput on connect, this banner is hidden from\n#   the user application.\n# - NOTIFY_MODEMSTATE: the poll interval of the server seems to be one\n#   second.\n# - To get the signature [COM_PORT_OPTION 0] has to be sent.\n# - run a server: run ser2net daemon, in /etc/ser2net.conf:\n#     2000:telnet:0:/dev/ttyS0:9600 remctl banner\n##############################################################################\n\n# How to identify ports? pySerial might want to support other protocols in the\n# future, so lets use an URL scheme.\n# for RFC2217 compliant servers we will use this:\n#    rfc2217://<host>:<port>[/option[/option...]]\n#\n# options:\n# - \"debug\" print diagnostic messages\n# - \"ign_set_control\": do not look at the answers to SET_CONTROL\n# - \"poll_modem\": issue NOTIFY_MODEMSTATE requests when CTS/DTR/RI/CD is read.\n#   Without this option it expects that the server sends notifications\n#   automatically on change (which most servers do and is according to the\n#   RFC).\n# the order of the options is not relevant\n\nfrom serial.serialutil import *\nimport time\nimport struct\nimport socket\nimport threading\nimport Queue\nimport logging\n\n# port string is expected to be something like this:\n# rfc2217://host:port\n# host may be an IP or including domain, whatever.\n# port is 0...65535\n\n# map log level names to constants. used in fromURL()\nLOGGER_LEVELS = {\n    'debug': logging.DEBUG,\n    'info': logging.INFO,\n    'warning': logging.WARNING,\n    'error': logging.ERROR,\n    }\n\n\n# telnet protocol characters\nIAC  = to_bytes([255]) # Interpret As Command\nDONT = to_bytes([254])\nDO   = to_bytes([253])\nWONT = to_bytes([252])\nWILL = to_bytes([251])\nIAC_DOUBLED = to_bytes([IAC, IAC])\n\nSE  = to_bytes([240])  # Subnegotiation End\nNOP = to_bytes([241])  # No Operation\nDM  = to_bytes([242])  # Data Mark\nBRK = to_bytes([243])  # Break\nIP  = to_bytes([244])  # Interrupt process\nAO  = to_bytes([245])  # Abort output\nAYT = to_bytes([246])  # Are You There\nEC  = to_bytes([247])  # Erase Character\nEL  = to_bytes([248])  # Erase Line\nGA  = to_bytes([249])  # Go Ahead\nSB =  to_bytes([250])  # Subnegotiation Begin\n\n# selected telnet options\nBINARY = to_bytes([0]) # 8-bit data path\nECHO = to_bytes([1])   # echo\nSGA = to_bytes([3])    # suppress go ahead\n\n# RFC2217\nCOM_PORT_OPTION = to_bytes([44])\n\n# Client to Access Server\nSET_BAUDRATE = to_bytes([1])\nSET_DATASIZE = to_bytes([2])\nSET_PARITY = to_bytes([3])\nSET_STOPSIZE = to_bytes([4])\nSET_CONTROL = to_bytes([5])\nNOTIFY_LINESTATE = to_bytes([6])\nNOTIFY_MODEMSTATE = to_bytes([7])\nFLOWCONTROL_SUSPEND = to_bytes([8])\nFLOWCONTROL_RESUME = to_bytes([9])\nSET_LINESTATE_MASK = to_bytes([10])\nSET_MODEMSTATE_MASK = to_bytes([11])\nPURGE_DATA = to_bytes([12])\n\nSERVER_SET_BAUDRATE = to_bytes([101])\nSERVER_SET_DATASIZE = to_bytes([102])\nSERVER_SET_PARITY = to_bytes([103])\nSERVER_SET_STOPSIZE = to_bytes([104])\nSERVER_SET_CONTROL = to_bytes([105])\nSERVER_NOTIFY_LINESTATE = to_bytes([106])\nSERVER_NOTIFY_MODEMSTATE = to_bytes([107])\nSERVER_FLOWCONTROL_SUSPEND = to_bytes([108])\nSERVER_FLOWCONTROL_RESUME = to_bytes([109])\nSERVER_SET_LINESTATE_MASK = to_bytes([110])\nSERVER_SET_MODEMSTATE_MASK = to_bytes([111])\nSERVER_PURGE_DATA = to_bytes([112])\n\nRFC2217_ANSWER_MAP = {\n    SET_BAUDRATE: SERVER_SET_BAUDRATE,\n    SET_DATASIZE: SERVER_SET_DATASIZE,\n    SET_PARITY: SERVER_SET_PARITY,\n    SET_STOPSIZE: SERVER_SET_STOPSIZE,\n    SET_CONTROL: SERVER_SET_CONTROL,\n    NOTIFY_LINESTATE: SERVER_NOTIFY_LINESTATE,\n    NOTIFY_MODEMSTATE: SERVER_NOTIFY_MODEMSTATE,\n    FLOWCONTROL_SUSPEND: SERVER_FLOWCONTROL_SUSPEND,\n    FLOWCONTROL_RESUME: SERVER_FLOWCONTROL_RESUME,\n    SET_LINESTATE_MASK: SERVER_SET_LINESTATE_MASK,\n    SET_MODEMSTATE_MASK: SERVER_SET_MODEMSTATE_MASK,\n    PURGE_DATA: SERVER_PURGE_DATA,\n}\n\nSET_CONTROL_REQ_FLOW_SETTING = to_bytes([0])        # Request Com Port Flow Control Setting (outbound/both)\nSET_CONTROL_USE_NO_FLOW_CONTROL = to_bytes([1])     # Use No Flow Control (outbound/both)\nSET_CONTROL_USE_SW_FLOW_CONTROL = to_bytes([2])     # Use XON/XOFF Flow Control (outbound/both)\nSET_CONTROL_USE_HW_FLOW_CONTROL = to_bytes([3])     # Use HARDWARE Flow Control (outbound/both)\nSET_CONTROL_REQ_BREAK_STATE = to_bytes([4])         # Request BREAK State\nSET_CONTROL_BREAK_ON = to_bytes([5])                # Set BREAK State ON\nSET_CONTROL_BREAK_OFF = to_bytes([6])               # Set BREAK State OFF\nSET_CONTROL_REQ_DTR = to_bytes([7])                 # Request DTR Signal State\nSET_CONTROL_DTR_ON = to_bytes([8])                  # Set DTR Signal State ON\nSET_CONTROL_DTR_OFF = to_bytes([9])                 # Set DTR Signal State OFF\nSET_CONTROL_REQ_RTS = to_bytes([10])                # Request RTS Signal State\nSET_CONTROL_RTS_ON = to_bytes([11])                 # Set RTS Signal State ON\nSET_CONTROL_RTS_OFF = to_bytes([12])                # Set RTS Signal State OFF\nSET_CONTROL_REQ_FLOW_SETTING_IN = to_bytes([13])    # Request Com Port Flow Control Setting (inbound)\nSET_CONTROL_USE_NO_FLOW_CONTROL_IN = to_bytes([14]) # Use No Flow Control (inbound)\nSET_CONTROL_USE_SW_FLOW_CONTOL_IN = to_bytes([15])  # Use XON/XOFF Flow Control (inbound)\nSET_CONTROL_USE_HW_FLOW_CONTOL_IN = to_bytes([16])  # Use HARDWARE Flow Control (inbound)\nSET_CONTROL_USE_DCD_FLOW_CONTROL = to_bytes([17])   # Use DCD Flow Control (outbound/both)\nSET_CONTROL_USE_DTR_FLOW_CONTROL = to_bytes([18])   # Use DTR Flow Control (inbound)\nSET_CONTROL_USE_DSR_FLOW_CONTROL = to_bytes([19])   # Use DSR Flow Control (outbound/both)\n\nLINESTATE_MASK_TIMEOUT = 128                # Time-out Error\nLINESTATE_MASK_SHIFTREG_EMPTY = 64          # Transfer Shift Register Empty\nLINESTATE_MASK_TRANSREG_EMPTY = 32          # Transfer Holding Register Empty\nLINESTATE_MASK_BREAK_DETECT = 16            # Break-detect Error\nLINESTATE_MASK_FRAMING_ERROR = 8            # Framing Error\nLINESTATE_MASK_PARTIY_ERROR = 4             # Parity Error\nLINESTATE_MASK_OVERRUN_ERROR = 2            # Overrun Error\nLINESTATE_MASK_DATA_READY = 1               # Data Ready\n\nMODEMSTATE_MASK_CD = 128                    # Receive Line Signal Detect (also known as Carrier Detect)\nMODEMSTATE_MASK_RI = 64                     # Ring Indicator\nMODEMSTATE_MASK_DSR = 32                    # Data-Set-Ready Signal State\nMODEMSTATE_MASK_CTS = 16                    # Clear-To-Send Signal State\nMODEMSTATE_MASK_CD_CHANGE = 8               # Delta Receive Line Signal Detect\nMODEMSTATE_MASK_RI_CHANGE = 4               # Trailing-edge Ring Detector\nMODEMSTATE_MASK_DSR_CHANGE = 2              # Delta Data-Set-Ready\nMODEMSTATE_MASK_CTS_CHANGE = 1              # Delta Clear-To-Send\n\nPURGE_RECEIVE_BUFFER = to_bytes([1])        # Purge access server receive data buffer\nPURGE_TRANSMIT_BUFFER = to_bytes([2])       # Purge access server transmit data buffer\nPURGE_BOTH_BUFFERS = to_bytes([3])          # Purge both the access server receive data buffer and the access server transmit data buffer\n\n\nRFC2217_PARITY_MAP = {\n    PARITY_NONE: 1,\n    PARITY_ODD: 2,\n    PARITY_EVEN: 3,\n    PARITY_MARK: 4,\n    PARITY_SPACE: 5,\n}\nRFC2217_REVERSE_PARITY_MAP = dict((v,k) for k,v in RFC2217_PARITY_MAP.items())\n\nRFC2217_STOPBIT_MAP = {\n    STOPBITS_ONE: 1,\n    STOPBITS_ONE_POINT_FIVE: 3,\n    STOPBITS_TWO: 2,\n}\nRFC2217_REVERSE_STOPBIT_MAP = dict((v,k) for k,v in RFC2217_STOPBIT_MAP.items())\n\n# Telnet filter states\nM_NORMAL = 0\nM_IAC_SEEN = 1\nM_NEGOTIATE = 2\n\n# TelnetOption and TelnetSubnegotiation states\nREQUESTED = 'REQUESTED'\nACTIVE = 'ACTIVE'\nINACTIVE = 'INACTIVE'\nREALLY_INACTIVE = 'REALLY_INACTIVE'\n\nclass TelnetOption(object):\n    \"\"\"Manage a single telnet option, keeps track of DO/DONT WILL/WONT.\"\"\"\n\n    def __init__(self, connection, name, option, send_yes, send_no, ack_yes, ack_no, initial_state, activation_callback=None):\n        \"\"\"Init option.\n        :param connection: connection used to transmit answers\n        :param name: a readable name for debug outputs\n        :param send_yes: what to send when option is to be enabled.\n        :param send_no: what to send when option is to be disabled.\n        :param ack_yes: what to expect when remote agrees on option.\n        :param ack_no: what to expect when remote disagrees on option.\n        :param initial_state: options initialized with REQUESTED are tried to\n            be enabled on startup. use INACTIVE for all others.\n        \"\"\"\n        self.connection = connection\n        self.name = name\n        self.option = option\n        self.send_yes = send_yes\n        self.send_no = send_no\n        self.ack_yes = ack_yes\n        self.ack_no = ack_no\n        self.state = initial_state\n        self.active = False\n        self.activation_callback = activation_callback\n\n    def __repr__(self):\n        \"\"\"String for debug outputs\"\"\"\n        return \"%s:%s(%s)\" % (self.name, self.active, self.state)\n\n    def process_incoming(self, command):\n        \"\"\"A DO/DONT/WILL/WONT was received for this option, update state and\n        answer when needed.\"\"\"\n        if command == self.ack_yes:\n            if self.state is REQUESTED:\n                self.state = ACTIVE\n                self.active = True\n                if self.activation_callback is not None:\n                    self.activation_callback()\n            elif self.state is ACTIVE:\n                pass\n            elif self.state is INACTIVE:\n                self.state = ACTIVE\n                self.connection.telnetSendOption(self.send_yes, self.option)\n                self.active = True\n                if self.activation_callback is not None:\n                    self.activation_callback()\n            elif self.state is REALLY_INACTIVE:\n                self.connection.telnetSendOption(self.send_no, self.option)\n            else:\n                raise ValueError('option in illegal state %r' % self)\n        elif command == self.ack_no:\n            if self.state is REQUESTED:\n                self.state = INACTIVE\n                self.active = False\n            elif self.state is ACTIVE:\n                self.state = INACTIVE\n                self.connection.telnetSendOption(self.send_no, self.option)\n                self.active = False\n            elif self.state is INACTIVE:\n                pass\n            elif self.state is REALLY_INACTIVE:\n                pass\n            else:\n                raise ValueError('option in illegal state %r' % self)\n\n\nclass TelnetSubnegotiation(object):\n    \"\"\"A object to handle subnegotiation of options. In this case actually\n    sub-sub options for RFC 2217. It is used to track com port options.\"\"\"\n\n    def __init__(self, connection, name, option, ack_option=None):\n        if ack_option is None: ack_option = option\n        self.connection = connection\n        self.name = name\n        self.option = option\n        self.value = None\n        self.ack_option = ack_option\n        self.state = INACTIVE\n\n    def __repr__(self):\n        \"\"\"String for debug outputs.\"\"\"\n        return \"%s:%s\" % (self.name, self.state)\n\n    def set(self, value):\n        \"\"\"request a change of the value. a request is sent to the server. if\n        the client needs to know if the change is performed he has to check the\n        state of this object.\"\"\"\n        self.value = value\n        self.state = REQUESTED\n        self.connection.rfc2217SendSubnegotiation(self.option, self.value)\n        if self.connection.logger:\n            self.connection.logger.debug(\"SB Requesting %s -> %r\" % (self.name, self.value))\n\n    def isReady(self):\n        \"\"\"check if answer from server has been received. when server rejects\n        the change, raise a ValueError.\"\"\"\n        if self.state == REALLY_INACTIVE:\n            raise ValueError(\"remote rejected value for option %r\" % (self.name))\n        return self.state == ACTIVE\n    # add property to have a similar interface as TelnetOption\n    active = property(isReady)\n\n    def wait(self, timeout=3):\n        \"\"\"wait until the subnegotiation has been acknowledged or timeout. It\n        can also throw a value error when the answer from the server does not\n        match the value sent.\"\"\"\n        timeout_time = time.time() + timeout\n        while time.time() < timeout_time:\n            time.sleep(0.05)    # prevent 100% CPU load\n            if self.isReady():\n                break\n        else:\n            raise SerialException(\"timeout while waiting for option %r\" % (self.name))\n\n    def checkAnswer(self, suboption):\n        \"\"\"check an incoming subnegotiation block. the parameter already has\n        cut off the header like sub option number and com port option value.\"\"\"\n        if self.value == suboption[:len(self.value)]:\n            self.state = ACTIVE\n        else:\n            # error propagation done in isReady\n            self.state = REALLY_INACTIVE\n        if self.connection.logger:\n            self.connection.logger.debug(\"SB Answer %s -> %r -> %s\" % (self.name, suboption, self.state))\n\n\nclass RFC2217Serial(SerialBase):\n    \"\"\"Serial port implementation for RFC 2217 remote serial ports.\"\"\"\n\n    BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,\n                 9600, 19200, 38400, 57600, 115200)\n\n    def open(self):\n        \"\"\"Open port with current settings. This may throw a SerialException\n           if the port cannot be opened.\"\"\"\n        self.logger = None\n        self._ignore_set_control_answer = False\n        self._poll_modem_state = False\n        self._network_timeout = 3\n        if self._port is None:\n            raise SerialException(\"Port must be configured before it can be used.\")\n        if self._isOpen:\n            raise SerialException(\"Port is already open.\")\n        try:\n            self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n            self._socket.connect(self.fromURL(self.portstr))\n            self._socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)\n        except Exception, msg:\n            self._socket = None\n            raise SerialException(\"Could not open port %s: %s\" % (self.portstr, msg))\n\n        self._socket.settimeout(5) # XXX good value?\n\n        # use a thread save queue as buffer. it also simplifies implementing\n        # the read timeout\n        self._read_buffer = Queue.Queue()\n        # to ensure that user writes does not interfere with internal\n        # telnet/rfc2217 options establish a lock\n        self._write_lock = threading.Lock()\n        # name the following separately so that, below, a check can be easily done\n        mandadory_options = [\n            TelnetOption(self, 'we-BINARY', BINARY, WILL, WONT, DO, DONT, INACTIVE),\n            TelnetOption(self, 'we-RFC2217', COM_PORT_OPTION, WILL, WONT, DO, DONT, REQUESTED),\n        ]\n        # all supported telnet options\n        self._telnet_options = [\n            TelnetOption(self, 'ECHO', ECHO, DO, DONT, WILL, WONT, REQUESTED),\n            TelnetOption(self, 'we-SGA', SGA, WILL, WONT, DO, DONT, REQUESTED),\n            TelnetOption(self, 'they-SGA', SGA, DO, DONT, WILL, WONT, REQUESTED),\n            TelnetOption(self, 'they-BINARY', BINARY, DO, DONT, WILL, WONT, INACTIVE),\n            TelnetOption(self, 'they-RFC2217', COM_PORT_OPTION, DO, DONT, WILL, WONT, REQUESTED),\n        ] + mandadory_options\n        # RFC 2217 specific states\n        # COM port settings\n        self._rfc2217_port_settings = {\n            'baudrate': TelnetSubnegotiation(self, 'baudrate', SET_BAUDRATE, SERVER_SET_BAUDRATE),\n            'datasize': TelnetSubnegotiation(self, 'datasize', SET_DATASIZE, SERVER_SET_DATASIZE),\n            'parity':   TelnetSubnegotiation(self, 'parity',   SET_PARITY,   SERVER_SET_PARITY),\n            'stopsize': TelnetSubnegotiation(self, 'stopsize', SET_STOPSIZE, SERVER_SET_STOPSIZE),\n            }\n        # There are more subnegotiation objects, combine all in one dictionary\n        # for easy access\n        self._rfc2217_options = {\n            'purge':    TelnetSubnegotiation(self, 'purge',    PURGE_DATA,   SERVER_PURGE_DATA),\n            'control':  TelnetSubnegotiation(self, 'control',  SET_CONTROL,  SERVER_SET_CONTROL),\n            }\n        self._rfc2217_options.update(self._rfc2217_port_settings)\n        # cache for line and modem states that the server sends to us\n        self._linestate = 0\n        self._modemstate = None\n        self._modemstate_expires = 0\n        # RFC 2217 flow control between server and client\n        self._remote_suspend_flow = False\n\n        self._thread = threading.Thread(target=self._telnetReadLoop)\n        self._thread.setDaemon(True)\n        self._thread.setName('pySerial RFC 2217 reader thread for %s' % (self._port,))\n        self._thread.start()\n\n        # negotiate Telnet/RFC 2217 -> send initial requests\n        for option in self._telnet_options:\n            if option.state is REQUESTED:\n                self.telnetSendOption(option.send_yes, option.option)\n        # now wait until important options are negotiated\n        timeout_time = time.time() + self._network_timeout\n        while time.time() < timeout_time:\n            time.sleep(0.05)    # prevent 100% CPU load\n            if sum(o.active for o in mandadory_options) == len(mandadory_options):\n                break\n        else:\n            raise SerialException(\"Remote does not seem to support RFC2217 or BINARY mode %r\" % mandadory_options)\n        if self.logger:\n            self.logger.info(\"Negotiated options: %s\" % self._telnet_options)\n\n        # fine, go on, set RFC 2271 specific things\n        self._reconfigurePort()\n        # all things set up get, now a clean start\n        self._isOpen = True\n        if not self._rtscts:\n            self.setRTS(True)\n            self.setDTR(True)\n        self.flushInput()\n        self.flushOutput()\n\n    def _reconfigurePort(self):\n        \"\"\"Set communication parameters on opened port.\"\"\"\n        if self._socket is None:\n            raise SerialException(\"Can only operate on open ports\")\n\n        # if self._timeout != 0 and self._interCharTimeout is not None:\n            # XXX\n\n        if self._writeTimeout is not None:\n            raise NotImplementedError('writeTimeout is currently not supported')\n            # XXX\n\n        # Setup the connection\n        # to get good performance, all parameter changes are sent first...\n        if not isinstance(self._baudrate, (int, long)) or not 0 < self._baudrate < 2**32:\n            raise ValueError(\"invalid baudrate: %r\" % (self._baudrate))\n        self._rfc2217_port_settings['baudrate'].set(struct.pack('!I', self._baudrate))\n        self._rfc2217_port_settings['datasize'].set(struct.pack('!B', self._bytesize))\n        self._rfc2217_port_settings['parity'].set(struct.pack('!B', RFC2217_PARITY_MAP[self._parity]))\n        self._rfc2217_port_settings['stopsize'].set(struct.pack('!B', RFC2217_STOPBIT_MAP[self._stopbits]))\n\n        # and now wait until parameters are active\n        items = self._rfc2217_port_settings.values()\n        if self.logger:\n            self.logger.debug(\"Negotiating settings: %s\" % (items,))\n        timeout_time = time.time() + self._network_timeout\n        while time.time() < timeout_time:\n            time.sleep(0.05)    # prevent 100% CPU load\n            if sum(o.active for o in items) == len(items):\n                break\n        else:\n            raise SerialException(\"Remote does not accept parameter change (RFC2217): %r\" % items)\n        if self.logger:\n            self.logger.info(\"Negotiated settings: %s\" % (items,))\n\n        if self._rtscts and self._xonxoff:\n            raise ValueError('xonxoff and rtscts together are not supported')\n        elif self._rtscts:\n            self.rfc2217SetControl(SET_CONTROL_USE_HW_FLOW_CONTROL)\n        elif self._xonxoff:\n            self.rfc2217SetControl(SET_CONTROL_USE_SW_FLOW_CONTROL)\n        else:\n            self.rfc2217SetControl(SET_CONTROL_USE_NO_FLOW_CONTROL)\n\n    def close(self):\n        \"\"\"Close port\"\"\"\n        if self._isOpen:\n            if self._socket:\n                try:\n                    self._socket.shutdown(socket.SHUT_RDWR)\n                    self._socket.close()\n                except:\n                    # ignore errors.\n                    pass\n                self._socket = None\n            if self._thread:\n                self._thread.join()\n            self._isOpen = False\n            # in case of quick reconnects, give the server some time\n            time.sleep(0.3)\n\n    def makeDeviceName(self, port):\n        raise SerialException(\"there is no sensible way to turn numbers into URLs\")\n\n    def fromURL(self, url):\n        \"\"\"extract host and port from an URL string\"\"\"\n        if url.lower().startswith(\"rfc2217://\"): url = url[10:]\n        try:\n            # is there a \"path\" (our options)?\n            if '/' in url:\n                # cut away options\n                url, options = url.split('/', 1)\n                # process options now, directly altering self\n                for option in options.split('/'):\n                    if '=' in option:\n                        option, value = option.split('=', 1)\n                    else:\n                        value = None\n                    if option == 'logging':\n                        logging.basicConfig()   # XXX is that good to call it here?\n                        self.logger = logging.getLogger('pySerial.rfc2217')\n                        self.logger.setLevel(LOGGER_LEVELS[value])\n                        self.logger.debug('enabled logging')\n                    elif option == 'ign_set_control':\n                        self._ignore_set_control_answer = True\n                    elif option == 'poll_modem':\n                        self._poll_modem_state = True\n                    elif option == 'timeout':\n                        self._network_timeout = float(value)\n                    else:\n                        raise ValueError('unknown option: %r' % (option,))\n            # get host and port\n            host, port = url.split(':', 1) # may raise ValueError because of unpacking\n            port = int(port)               # and this if it's not a number\n            if not 0 <= port < 65536: raise ValueError(\"port not in range 0...65535\")\n        except ValueError, e:\n            raise SerialException('expected a string in the form \"[rfc2217://]<host>:<port>[/option[/option...]]\": %s' % e)\n        return (host, port)\n\n    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n\n    def inWaiting(self):\n        \"\"\"Return the number of characters currently in the input buffer.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        return self._read_buffer.qsize()\n\n    def read(self, size=1):\n        \"\"\"Read size bytes from the serial port. If a timeout is set it may\n        return less characters as requested. With no timeout it will block\n        until the requested number of bytes is read.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        data = bytearray()\n        try:\n            while len(data) < size:\n                if self._thread is None:\n                    raise SerialException('connection failed (reader thread died)')\n                data.append(self._read_buffer.get(True, self._timeout))\n        except Queue.Empty: # -> timeout\n            pass\n        return bytes(data)\n\n    def write(self, data):\n        \"\"\"Output the given string over the serial port. Can block if the\n        connection is blocked. May raise SerialException if the connection is\n        closed.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        self._write_lock.acquire()\n        try:\n            try:\n                self._socket.sendall(data.replace(IAC, IAC_DOUBLED))\n            except socket.error, e:\n                raise SerialException(\"connection failed (socket error): %s\" % e) # XXX what exception if socket connection fails\n        finally:\n            self._write_lock.release()\n        return len(data)\n\n    def flushInput(self):\n        \"\"\"Clear input buffer, discarding all that is in the buffer.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        self.rfc2217SendPurge(PURGE_RECEIVE_BUFFER)\n        # empty read buffer\n        while self._read_buffer.qsize():\n            self._read_buffer.get(False)\n\n    def flushOutput(self):\n        \"\"\"Clear output buffer, aborting the current output and\n        discarding all that is in the buffer.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        self.rfc2217SendPurge(PURGE_TRANSMIT_BUFFER)\n\n    def sendBreak(self, duration=0.25):\n        \"\"\"Send break condition. Timed, returns to idle state after given\n        duration.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        self.setBreak(True)\n        time.sleep(duration)\n        self.setBreak(False)\n\n    def setBreak(self, level=True):\n        \"\"\"Set break: Controls TXD. When active, to transmitting is\n        possible.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('set BREAK to %s' % ('inactive', 'active')[bool(level)])\n        if level:\n            self.rfc2217SetControl(SET_CONTROL_BREAK_ON)\n        else:\n            self.rfc2217SetControl(SET_CONTROL_BREAK_OFF)\n\n    def setRTS(self, level=True):\n        \"\"\"Set terminal status line: Request To Send.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('set RTS to %s' % ('inactive', 'active')[bool(level)])\n        if level:\n            self.rfc2217SetControl(SET_CONTROL_RTS_ON)\n        else:\n            self.rfc2217SetControl(SET_CONTROL_RTS_OFF)\n\n    def setDTR(self, level=True):\n        \"\"\"Set terminal status line: Data Terminal Ready.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('set DTR to %s' % ('inactive', 'active')[bool(level)])\n        if level:\n            self.rfc2217SetControl(SET_CONTROL_DTR_ON)\n        else:\n            self.rfc2217SetControl(SET_CONTROL_DTR_OFF)\n\n    def getCTS(self):\n        \"\"\"Read terminal status line: Clear To Send.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        return bool(self.getModemState() & MODEMSTATE_MASK_CTS)\n\n    def getDSR(self):\n        \"\"\"Read terminal status line: Data Set Ready.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        return bool(self.getModemState() & MODEMSTATE_MASK_DSR)\n\n    def getRI(self):\n        \"\"\"Read terminal status line: Ring Indicator.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        return bool(self.getModemState() & MODEMSTATE_MASK_RI)\n\n    def getCD(self):\n        \"\"\"Read terminal status line: Carrier Detect.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        return bool(self.getModemState() & MODEMSTATE_MASK_CD)\n\n    # - - - platform specific - - -\n    # None so far\n\n    # - - - RFC2217 specific - - -\n\n    def _telnetReadLoop(self):\n        \"\"\"read loop for the socket.\"\"\"\n        mode = M_NORMAL\n        suboption = None\n        try:\n            while self._socket is not None:\n                try:\n                    data = self._socket.recv(1024)\n                except socket.timeout:\n                    # just need to get out of recv form time to time to check if\n                    # still alive\n                    continue\n                except socket.error, e:\n                    # connection fails -> terminate loop\n                    if self.logger:\n                        self.logger.debug(\"socket error in reader thread: %s\" % (e,))\n                    break\n                if not data: break # lost connection\n                for byte in data:\n                    if mode == M_NORMAL:\n                        # interpret as command or as data\n                        if byte == IAC:\n                            mode = M_IAC_SEEN\n                        else:\n                            # store data in read buffer or sub option buffer\n                            # depending on state\n                            if suboption is not None:\n                                suboption.append(byte)\n                            else:\n                                self._read_buffer.put(byte)\n                    elif mode == M_IAC_SEEN:\n                        if byte == IAC:\n                            # interpret as command doubled -> insert character\n                            # itself\n                            if suboption is not None:\n                                suboption.append(IAC)\n                            else:\n                                self._read_buffer.put(IAC)\n                            mode = M_NORMAL\n                        elif byte == SB:\n                            # sub option start\n                            suboption = bytearray()\n                            mode = M_NORMAL\n                        elif byte == SE:\n                            # sub option end -> process it now\n                            self._telnetProcessSubnegotiation(bytes(suboption))\n                            suboption = None\n                            mode = M_NORMAL\n                        elif byte in (DO, DONT, WILL, WONT):\n                            # negotiation\n                            telnet_command = byte\n                            mode = M_NEGOTIATE\n                        else:\n                            # other telnet commands\n                            self._telnetProcessCommand(byte)\n                            mode = M_NORMAL\n                    elif mode == M_NEGOTIATE: # DO, DONT, WILL, WONT was received, option now following\n                        self._telnetNegotiateOption(telnet_command, byte)\n                        mode = M_NORMAL\n        finally:\n            self._thread = None\n            if self.logger:\n                self.logger.debug(\"read thread terminated\")\n\n    # - incoming telnet commands and options\n\n    def _telnetProcessCommand(self, command):\n        \"\"\"Process commands other than DO, DONT, WILL, WONT.\"\"\"\n        # Currently none. RFC2217 only uses negotiation and subnegotiation.\n        if self.logger:\n            self.logger.warning(\"ignoring Telnet command: %r\" % (command,))\n\n    def _telnetNegotiateOption(self, command, option):\n        \"\"\"Process incoming DO, DONT, WILL, WONT.\"\"\"\n        # check our registered telnet options and forward command to them\n        # they know themselves if they have to answer or not\n        known = False\n        for item in self._telnet_options:\n            # can have more than one match! as some options are duplicated for\n            # 'us' and 'them'\n            if item.option == option:\n                item.process_incoming(command)\n                known = True\n        if not known:\n            # handle unknown options\n            # only answer to positive requests and deny them\n            if command == WILL or command == DO:\n                self.telnetSendOption((command == WILL and DONT or WONT), option)\n                if self.logger:\n                    self.logger.warning(\"rejected Telnet option: %r\" % (option,))\n\n\n    def _telnetProcessSubnegotiation(self, suboption):\n        \"\"\"Process subnegotiation, the data between IAC SB and IAC SE.\"\"\"\n        if suboption[0:1] == COM_PORT_OPTION:\n            if suboption[1:2] == SERVER_NOTIFY_LINESTATE and len(suboption) >= 3:\n                self._linestate = ord(suboption[2:3]) # ensure it is a number\n                if self.logger:\n                    self.logger.info(\"NOTIFY_LINESTATE: %s\" % self._linestate)\n            elif suboption[1:2] == SERVER_NOTIFY_MODEMSTATE and len(suboption) >= 3:\n                self._modemstate = ord(suboption[2:3]) # ensure it is a number\n                if self.logger:\n                    self.logger.info(\"NOTIFY_MODEMSTATE: %s\" % self._modemstate)\n                # update time when we think that a poll would make sense\n                self._modemstate_expires = time.time() + 0.3\n            elif suboption[1:2] == FLOWCONTROL_SUSPEND:\n                self._remote_suspend_flow = True\n            elif suboption[1:2] == FLOWCONTROL_RESUME:\n                self._remote_suspend_flow = False\n            else:\n                for item in self._rfc2217_options.values():\n                    if item.ack_option == suboption[1:2]:\n                        #~ print \"processing COM_PORT_OPTION: %r\" % list(suboption[1:])\n                        item.checkAnswer(bytes(suboption[2:]))\n                        break\n                else:\n                    if self.logger:\n                        self.logger.warning(\"ignoring COM_PORT_OPTION: %r\" % (suboption,))\n        else:\n            if self.logger:\n                self.logger.warning(\"ignoring subnegotiation: %r\" % (suboption,))\n\n    # - outgoing telnet commands and options\n\n    def _internal_raw_write(self, data):\n        \"\"\"internal socket write with no data escaping. used to send telnet stuff.\"\"\"\n        self._write_lock.acquire()\n        try:\n            self._socket.sendall(data)\n        finally:\n            self._write_lock.release()\n\n    def telnetSendOption(self, action, option):\n        \"\"\"Send DO, DONT, WILL, WONT.\"\"\"\n        self._internal_raw_write(to_bytes([IAC, action, option]))\n\n    def rfc2217SendSubnegotiation(self, option, value=''):\n        \"\"\"Subnegotiation of RFC2217 parameters.\"\"\"\n        value = value.replace(IAC, IAC_DOUBLED)\n        self._internal_raw_write(to_bytes([IAC, SB, COM_PORT_OPTION, option] + list(value) + [IAC, SE]))\n\n    def rfc2217SendPurge(self, value):\n        item = self._rfc2217_options['purge']\n        item.set(value) # transmit desired purge type\n        item.wait(self._network_timeout) # wait for acknowledge from the server\n\n    def rfc2217SetControl(self, value):\n        item = self._rfc2217_options['control']\n        item.set(value) # transmit desired control type\n        if self._ignore_set_control_answer:\n            # answers are ignored when option is set. compatibility mode for\n            # servers that answer, but not the expected one... (or no answer\n            # at all) i.e. sredird\n            time.sleep(0.1)  # this helps getting the unit tests passed\n        else:\n            item.wait(self._network_timeout)  # wait for acknowledge from the server\n\n    def rfc2217FlowServerReady(self):\n        \"\"\"check if server is ready to receive data. block for some time when\n        not.\"\"\"\n        #~ if self._remote_suspend_flow:\n            #~ wait---\n\n    def getModemState(self):\n        \"\"\"get last modem state (cached value. if value is \"old\", request a new\n        one. this cache helps that we don't issue to many requests when e.g. all\n        status lines, one after the other is queried by te user (getCTS, getDSR\n        etc.)\"\"\"\n        # active modem state polling enabled? is the value fresh enough?\n        if self._poll_modem_state and self._modemstate_expires < time.time():\n            if self.logger:\n                self.logger.debug('polling modem state')\n            # when it is older, request an update\n            self.rfc2217SendSubnegotiation(NOTIFY_MODEMSTATE)\n            timeout_time = time.time() + self._network_timeout\n            while time.time() < timeout_time:\n                time.sleep(0.05)    # prevent 100% CPU load\n                # when expiration time is updated, it means that there is a new\n                # value\n                if self._modemstate_expires > time.time():\n                    if self.logger:\n                        self.logger.warning('poll for modem state failed')\n                    break\n            # even when there is a timeout, do not generate an error just\n            # return the last known value. this way we can support buggy\n            # servers that do not respond to polls, but send automatic\n            # updates.\n        if self._modemstate is not None:\n            if self.logger:\n                self.logger.debug('using cached modem state')\n            return self._modemstate\n        else:\n            # never received a notification from the server\n            raise SerialException(\"remote sends no NOTIFY_MODEMSTATE\")\n\n\n# assemble Serial class with the platform specific implementation and the base\n# for file-like behavior. for Python 2.6 and newer, that provide the new I/O\n# library, derive from io.RawIOBase\ntry:\n    import io\nexcept ImportError:\n    # classic version with our own file-like emulation\n    class Serial(RFC2217Serial, FileLike):\n        pass\nelse:\n    # io library present\n    class Serial(RFC2217Serial, io.RawIOBase):\n        pass\n\n\n#############################################################################\n# The following is code that helps implementing an RFC 2217 server.\n\nclass PortManager(object):\n    \"\"\"This class manages the state of Telnet and RFC 2217. It needs a serial\n    instance and a connection to work with. Connection is expected to implement\n    a (thread safe) write function, that writes the string to the network.\"\"\"\n\n    def __init__(self, serial_port, connection, logger=None):\n        self.serial = serial_port\n        self.connection = connection\n        self.logger = logger\n        self._client_is_rfc2217 = False\n\n        # filter state machine\n        self.mode = M_NORMAL\n        self.suboption = None\n        self.telnet_command = None\n\n        # states for modem/line control events\n        self.modemstate_mask = 255\n        self.last_modemstate = None\n        self.linstate_mask = 0\n\n        # all supported telnet options\n        self._telnet_options = [\n            TelnetOption(self, 'ECHO', ECHO, WILL, WONT, DO, DONT, REQUESTED),\n            TelnetOption(self, 'we-SGA', SGA, WILL, WONT, DO, DONT, REQUESTED),\n            TelnetOption(self, 'they-SGA', SGA, DO, DONT, WILL, WONT, INACTIVE),\n            TelnetOption(self, 'we-BINARY', BINARY, WILL, WONT, DO, DONT, INACTIVE),\n            TelnetOption(self, 'they-BINARY', BINARY, DO, DONT, WILL, WONT, REQUESTED),\n            TelnetOption(self, 'we-RFC2217', COM_PORT_OPTION, WILL, WONT, DO, DONT, REQUESTED, self._client_ok),\n            TelnetOption(self, 'they-RFC2217', COM_PORT_OPTION, DO, DONT, WILL, WONT, INACTIVE, self._client_ok),\n            ]\n\n        # negotiate Telnet/RFC2217 -> send initial requests\n        if self.logger:\n            self.logger.debug(\"requesting initial Telnet/RFC 2217 options\")\n        for option in self._telnet_options:\n            if option.state is REQUESTED:\n                self.telnetSendOption(option.send_yes, option.option)\n        # issue 1st modem state notification\n\n    def _client_ok(self):\n        \"\"\"callback of telnet option. it gets called when option is activated.\n        this one here is used to detect when the client agrees on RFC 2217. a\n        flag is set so that other functions like check_modem_lines know if the\n        client is ok.\"\"\"\n        # The callback is used for we and they so if one party agrees, we're\n        # already happy. it seems not all servers do the negotiation correctly\n        # and i guess there are incorrect clients too.. so be happy if client\n        # answers one or the other positively.\n        self._client_is_rfc2217 = True\n        if self.logger:\n            self.logger.info(\"client accepts RFC 2217\")\n        # this is to ensure that the client gets a notification, even if there\n        # was no change\n        self.check_modem_lines(force_notification=True)\n\n    # - outgoing telnet commands and options\n\n    def telnetSendOption(self, action, option):\n        \"\"\"Send DO, DONT, WILL, WONT.\"\"\"\n        self.connection.write(to_bytes([IAC, action, option]))\n\n    def rfc2217SendSubnegotiation(self, option, value=''):\n        \"\"\"Subnegotiation of RFC 2217 parameters.\"\"\"\n        value = value.replace(IAC, IAC_DOUBLED)\n        self.connection.write(to_bytes([IAC, SB, COM_PORT_OPTION, option] + list(value) + [IAC, SE]))\n\n    # - check modem lines, needs to be called periodically from user to\n    # establish polling\n\n    def check_modem_lines(self, force_notification=False):\n        modemstate = (\n            (self.serial.getCTS() and MODEMSTATE_MASK_CTS) |\n            (self.serial.getDSR() and MODEMSTATE_MASK_DSR) |\n            (self.serial.getRI() and MODEMSTATE_MASK_RI) |\n            (self.serial.getCD() and MODEMSTATE_MASK_CD)\n        )\n        # check what has changed\n        deltas = modemstate ^ (self.last_modemstate or 0) # when last is None -> 0\n        if deltas & MODEMSTATE_MASK_CTS:\n            modemstate |= MODEMSTATE_MASK_CTS_CHANGE\n        if deltas & MODEMSTATE_MASK_DSR:\n            modemstate |= MODEMSTATE_MASK_DSR_CHANGE\n        if deltas & MODEMSTATE_MASK_RI:\n            modemstate |= MODEMSTATE_MASK_RI_CHANGE\n        if deltas & MODEMSTATE_MASK_CD:\n            modemstate |= MODEMSTATE_MASK_CD_CHANGE\n        # if new state is different and the mask allows this change, send\n        # notification. suppress notifications when client is not rfc2217\n        if modemstate != self.last_modemstate or force_notification:\n            if (self._client_is_rfc2217 and (modemstate & self.modemstate_mask)) or force_notification:\n                self.rfc2217SendSubnegotiation(\n                    SERVER_NOTIFY_MODEMSTATE,\n                    to_bytes([modemstate & self.modemstate_mask])\n                    )\n                if self.logger:\n                    self.logger.info(\"NOTIFY_MODEMSTATE: %s\" % (modemstate,))\n            # save last state, but forget about deltas.\n            # otherwise it would also notify about changing deltas which is\n            # probably not very useful\n            self.last_modemstate = modemstate & 0xf0\n\n    # - outgoing data escaping\n\n    def escape(self, data):\n        \"\"\"this generator function is for the user. all outgoing data has to be\n        properly escaped, so that no IAC character in the data stream messes up\n        the Telnet state machine in the server.\n\n        socket.sendall(escape(data))\n        \"\"\"\n        for byte in data:\n            if byte == IAC:\n                yield IAC\n                yield IAC\n            else:\n                yield byte\n\n    # - incoming data filter\n\n    def filter(self, data):\n        \"\"\"handle a bunch of incoming bytes. this is a generator. it will yield\n        all characters not of interest for Telnet/RFC 2217.\n\n        The idea is that the reader thread pushes data from the socket through\n        this filter:\n\n        for byte in filter(socket.recv(1024)):\n            # do things like CR/LF conversion/whatever\n            # and write data to the serial port\n            serial.write(byte)\n\n        (socket error handling code left as exercise for the reader)\n        \"\"\"\n        for byte in data:\n            if self.mode == M_NORMAL:\n                # interpret as command or as data\n                if byte == IAC:\n                    self.mode = M_IAC_SEEN\n                else:\n                    # store data in sub option buffer or pass it to our\n                    # consumer depending on state\n                    if self.suboption is not None:\n                        self.suboption.append(byte)\n                    else:\n                        yield byte\n            elif self.mode == M_IAC_SEEN:\n                if byte == IAC:\n                    # interpret as command doubled -> insert character\n                    # itself\n                    if self.suboption is not None:\n                        self.suboption.append(byte)\n                    else:\n                        yield byte\n                    self.mode = M_NORMAL\n                elif byte == SB:\n                    # sub option start\n                    self.suboption = bytearray()\n                    self.mode = M_NORMAL\n                elif byte == SE:\n                    # sub option end -> process it now\n                    self._telnetProcessSubnegotiation(bytes(self.suboption))\n                    self.suboption = None\n                    self.mode = M_NORMAL\n                elif byte in (DO, DONT, WILL, WONT):\n                    # negotiation\n                    self.telnet_command = byte\n                    self.mode = M_NEGOTIATE\n                else:\n                    # other telnet commands\n                    self._telnetProcessCommand(byte)\n                    self.mode = M_NORMAL\n            elif self.mode == M_NEGOTIATE: # DO, DONT, WILL, WONT was received, option now following\n                self._telnetNegotiateOption(self.telnet_command, byte)\n                self.mode = M_NORMAL\n\n    # - incoming telnet commands and options\n\n    def _telnetProcessCommand(self, command):\n        \"\"\"Process commands other than DO, DONT, WILL, WONT.\"\"\"\n        # Currently none. RFC2217 only uses negotiation and subnegotiation.\n        if self.logger:\n            self.logger.warning(\"ignoring Telnet command: %r\" % (command,))\n\n    def _telnetNegotiateOption(self, command, option):\n        \"\"\"Process incoming DO, DONT, WILL, WONT.\"\"\"\n        # check our registered telnet options and forward command to them\n        # they know themselves if they have to answer or not\n        known = False\n        for item in self._telnet_options:\n            # can have more than one match! as some options are duplicated for\n            # 'us' and 'them'\n            if item.option == option:\n                item.process_incoming(command)\n                known = True\n        if not known:\n            # handle unknown options\n            # only answer to positive requests and deny them\n            if command == WILL or command == DO:\n                self.telnetSendOption((command == WILL and DONT or WONT), option)\n                if self.logger:\n                    self.logger.warning(\"rejected Telnet option: %r\" % (option,))\n\n\n    def _telnetProcessSubnegotiation(self, suboption):\n        \"\"\"Process subnegotiation, the data between IAC SB and IAC SE.\"\"\"\n        if suboption[0:1] == COM_PORT_OPTION:\n            if self.logger:\n                self.logger.debug('received COM_PORT_OPTION: %r' % (suboption,))\n            if suboption[1:2] == SET_BAUDRATE:\n                backup = self.serial.baudrate\n                try:\n                    (self.serial.baudrate,) = struct.unpack(\"!I\", suboption[2:6])\n                except ValueError, e:\n                    if self.logger:\n                        self.logger.error(\"failed to set baud rate: %s\" % (e,))\n                    self.serial.baudrate = backup\n                else:\n                    if self.logger:\n                        self.logger.info(\"changed baud rate: %s\" % (self.serial.baudrate,))\n                self.rfc2217SendSubnegotiation(SERVER_SET_BAUDRATE, struct.pack(\"!I\", self.serial.baudrate))\n            elif suboption[1:2] == SET_DATASIZE:\n                backup = self.serial.bytesize\n                try:\n                    (self.serial.bytesize,) = struct.unpack(\"!B\", suboption[2:3])\n                except ValueError, e:\n                    if self.logger:\n                        self.logger.error(\"failed to set data size: %s\" % (e,))\n                    self.serial.bytesize = backup\n                else:\n                    if self.logger:\n                        self.logger.info(\"changed data size: %s\" % (self.serial.bytesize,))\n                self.rfc2217SendSubnegotiation(SERVER_SET_DATASIZE, struct.pack(\"!B\", self.serial.bytesize))\n            elif suboption[1:2] == SET_PARITY:\n                backup = self.serial.parity\n                try:\n                    self.serial.parity = RFC2217_REVERSE_PARITY_MAP[struct.unpack(\"!B\", suboption[2:3])[0]]\n                except ValueError, e:\n                    if self.logger:\n                        self.logger.error(\"failed to set parity: %s\" % (e,))\n                    self.serial.parity = backup\n                else:\n                    if self.logger:\n                        self.logger.info(\"changed parity: %s\" % (self.serial.parity,))\n                self.rfc2217SendSubnegotiation(\n                    SERVER_SET_PARITY,\n                    struct.pack(\"!B\", RFC2217_PARITY_MAP[self.serial.parity])\n                    )\n            elif suboption[1:2] == SET_STOPSIZE:\n                backup = self.serial.stopbits\n                try:\n                    self.serial.stopbits = RFC2217_REVERSE_STOPBIT_MAP[struct.unpack(\"!B\", suboption[2:3])[0]]\n                except ValueError, e:\n                    if self.logger:\n                        self.logger.error(\"failed to set stop bits: %s\" % (e,))\n                    self.serial.stopbits = backup\n                else:\n                    if self.logger:\n                        self.logger.info(\"changed stop bits: %s\" % (self.serial.stopbits,))\n                self.rfc2217SendSubnegotiation(\n                    SERVER_SET_STOPSIZE,\n                    struct.pack(\"!B\", RFC2217_STOPBIT_MAP[self.serial.stopbits])\n                    )\n            elif suboption[1:2] == SET_CONTROL:\n                if suboption[2:3] == SET_CONTROL_REQ_FLOW_SETTING:\n                    if self.serial.xonxoff:\n                        self.rfc2217SendSubnegotiation(SERVER_SET_CONTROL, SET_CONTROL_USE_SW_FLOW_CONTROL)\n                    elif self.serial.rtscts:\n                        self.rfc2217SendSubnegotiation(SERVER_SET_CONTROL, SET_CONTROL_USE_HW_FLOW_CONTROL)\n                    else:\n                        self.rfc2217SendSubnegotiation(SERVER_SET_CONTROL, SET_CONTROL_USE_NO_FLOW_CONTROL)\n                elif suboption[2:3] == SET_CONTROL_USE_NO_FLOW_CONTROL:\n                    self.serial.xonxoff = False\n                    self.serial.rtscts = False\n                    if self.logger:\n                        self.logger.info(\"changed flow control to None\")\n                    self.rfc2217SendSubnegotiation(SERVER_SET_CONTROL, SET_CONTROL_USE_NO_FLOW_CONTROL)\n                elif suboption[2:3] == SET_CONTROL_USE_SW_FLOW_CONTROL:\n                    self.serial.xonxoff = True\n                    if self.logger:\n                        self.logger.info(\"changed flow control to XON/XOFF\")\n                    self.rfc2217SendSubnegotiation(SERVER_SET_CONTROL, SET_CONTROL_USE_SW_FLOW_CONTROL)\n                elif suboption[2:3] == SET_CONTROL_USE_HW_FLOW_CONTROL:\n                    self.serial.rtscts = True\n                    if self.logger:\n                        self.logger.info(\"changed flow control to RTS/CTS\")\n                    self.rfc2217SendSubnegotiation(SERVER_SET_CONTROL, SET_CONTROL_USE_HW_FLOW_CONTROL)\n                elif suboption[2:3] == SET_CONTROL_REQ_BREAK_STATE:\n                    if self.logger:\n                        self.logger.warning(\"requested break state - not implemented\")\n                    pass # XXX needs cached value\n                elif suboption[2:3] == SET_CONTROL_BREAK_ON:\n                    self.serial.setBreak(True)\n                    if self.logger:\n                        self.logger.info(\"changed BREAK to active\")\n                    self.rfc2217SendSubnegotiation(SERVER_SET_CONTROL, SET_CONTROL_BREAK_ON)\n                elif suboption[2:3] == SET_CONTROL_BREAK_OFF:\n                    self.serial.setBreak(False)\n                    if self.logger:\n                        self.logger.info(\"changed BREAK to inactive\")\n                    self.rfc2217SendSubnegotiation(SERVER_SET_CONTROL, SET_CONTROL_BREAK_OFF)\n                elif suboption[2:3] == SET_CONTROL_REQ_DTR:\n                    if self.logger:\n                        self.logger.warning(\"requested DTR state - not implemented\")\n                    pass # XXX needs cached value\n                elif suboption[2:3] == SET_CONTROL_DTR_ON:\n                    self.serial.setDTR(True)\n                    if self.logger:\n                        self.logger.info(\"changed DTR to active\")\n                    self.rfc2217SendSubnegotiation(SERVER_SET_CONTROL, SET_CONTROL_DTR_ON)\n                elif suboption[2:3] == SET_CONTROL_DTR_OFF:\n                    self.serial.setDTR(False)\n                    if self.logger:\n                        self.logger.info(\"changed DTR to inactive\")\n                    self.rfc2217SendSubnegotiation(SERVER_SET_CONTROL, SET_CONTROL_DTR_OFF)\n                elif suboption[2:3] == SET_CONTROL_REQ_RTS:\n                    if self.logger:\n                        self.logger.warning(\"requested RTS state - not implemented\")\n                    pass # XXX needs cached value\n                    #~ self.rfc2217SendSubnegotiation(SERVER_SET_CONTROL, SET_CONTROL_RTS_ON)\n                elif suboption[2:3] == SET_CONTROL_RTS_ON:\n                    self.serial.setRTS(True)\n                    if self.logger:\n                        self.logger.info(\"changed RTS to active\")\n                    self.rfc2217SendSubnegotiation(SERVER_SET_CONTROL, SET_CONTROL_RTS_ON)\n                elif suboption[2:3] == SET_CONTROL_RTS_OFF:\n                    self.serial.setRTS(False)\n                    if self.logger:\n                        self.logger.info(\"changed RTS to inactive\")\n                    self.rfc2217SendSubnegotiation(SERVER_SET_CONTROL, SET_CONTROL_RTS_OFF)\n                #~ elif suboption[2:3] == SET_CONTROL_REQ_FLOW_SETTING_IN:\n                #~ elif suboption[2:3] == SET_CONTROL_USE_NO_FLOW_CONTROL_IN:\n                #~ elif suboption[2:3] == SET_CONTROL_USE_SW_FLOW_CONTOL_IN:\n                #~ elif suboption[2:3] == SET_CONTROL_USE_HW_FLOW_CONTOL_IN:\n                #~ elif suboption[2:3] == SET_CONTROL_USE_DCD_FLOW_CONTROL:\n                #~ elif suboption[2:3] == SET_CONTROL_USE_DTR_FLOW_CONTROL:\n                #~ elif suboption[2:3] == SET_CONTROL_USE_DSR_FLOW_CONTROL:\n            elif suboption[1:2] == NOTIFY_LINESTATE:\n                # client polls for current state\n                self.rfc2217SendSubnegotiation(\n                    SERVER_NOTIFY_LINESTATE,\n                    to_bytes([0])   # sorry, nothing like that implemented\n                    )\n            elif suboption[1:2] == NOTIFY_MODEMSTATE:\n                if self.logger:\n                    self.logger.info(\"request for modem state\")\n                # client polls for current state\n                self.check_modem_lines(force_notification=True)\n            elif suboption[1:2] == FLOWCONTROL_SUSPEND:\n                if self.logger:\n                    self.logger.info(\"suspend\")\n                self._remote_suspend_flow = True\n            elif suboption[1:2] == FLOWCONTROL_RESUME:\n                if self.logger:\n                    self.logger.info(\"resume\")\n                self._remote_suspend_flow = False\n            elif suboption[1:2] == SET_LINESTATE_MASK:\n                self.linstate_mask = ord(suboption[2:3]) # ensure it is a number\n                if self.logger:\n                    self.logger.info(\"line state mask: 0x%02x\" % (self.linstate_mask,))\n            elif suboption[1:2] == SET_MODEMSTATE_MASK:\n                self.modemstate_mask = ord(suboption[2:3]) # ensure it is a number\n                if self.logger:\n                    self.logger.info(\"modem state mask: 0x%02x\" % (self.modemstate_mask,))\n            elif suboption[1:2] == PURGE_DATA:\n                if suboption[2:3] == PURGE_RECEIVE_BUFFER:\n                    self.serial.flushInput()\n                    if self.logger:\n                        self.logger.info(\"purge in\")\n                    self.rfc2217SendSubnegotiation(SERVER_PURGE_DATA, PURGE_RECEIVE_BUFFER)\n                elif suboption[2:3] == PURGE_TRANSMIT_BUFFER:\n                    self.serial.flushOutput()\n                    if self.logger:\n                        self.logger.info(\"purge out\")\n                    self.rfc2217SendSubnegotiation(SERVER_PURGE_DATA, PURGE_TRANSMIT_BUFFER)\n                elif suboption[2:3] == PURGE_BOTH_BUFFERS:\n                    self.serial.flushInput()\n                    self.serial.flushOutput()\n                    if self.logger:\n                        self.logger.info(\"purge both\")\n                    self.rfc2217SendSubnegotiation(SERVER_PURGE_DATA, PURGE_BOTH_BUFFERS)\n                else:\n                    if self.logger:\n                        self.logger.error(\"undefined PURGE_DATA: %r\" % list(suboption[2:]))\n            else:\n                if self.logger:\n                    self.logger.error(\"undefined COM_PORT_OPTION: %r\" % list(suboption[1:]))\n        else:\n            if self.logger:\n                self.logger.warning(\"unknown subnegotiation: %r\" % (suboption,))\n\n\n# simple client test\nif __name__ == '__main__':\n    import sys\n    s = Serial('rfc2217://localhost:7000', 115200)\n    sys.stdout.write('%s\\n' % s)\n\n    #~ s.baudrate = 1898\n\n    sys.stdout.write(\"write...\\n\")\n    s.write(\"hello\\n\")\n    s.flush()\n    sys.stdout.write(\"read: %s\\n\" % s.read(5))\n\n    #~ s.baudrate = 19200\n    #~ s.databits = 7\n    s.close()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/serialcli.py",
    "content": "#! python\n# Python Serial Port Extension for Win32, Linux, BSD, Jython and .NET/Mono\n# serial driver for .NET/Mono (IronPython), .NET >= 2\n# see __init__.py\n#\n# (C) 2008 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n\nimport clr\nimport System\nimport System.IO.Ports\nfrom serial.serialutil import *\n\n\ndef device(portnum):\n    \"\"\"Turn a port number into a device name\"\"\"\n    return System.IO.Ports.SerialPort.GetPortNames()[portnum]\n\n\n# must invoke function with byte array, make a helper to convert strings\n# to byte arrays\nsab = System.Array[System.Byte]\ndef as_byte_array(string):\n    return sab([ord(x) for x in string])  # XXX will require adaption when run with a 3.x compatible IronPython\n\nclass IronSerial(SerialBase):\n    \"\"\"Serial port implemenation for .NET/Mono.\"\"\"\n\n    BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,\n                9600, 19200, 38400, 57600, 115200)\n\n    def open(self):\n        \"\"\"Open port with current settings. This may throw a SerialException\n           if the port cannot be opened.\"\"\"\n        if self._port is None:\n            raise SerialException(\"Port must be configured before it can be used.\")\n        if self._isOpen:\n            raise SerialException(\"Port is already open.\")\n        try:\n            self._port_handle = System.IO.Ports.SerialPort(self.portstr)\n        except Exception, msg:\n            self._port_handle = None\n            raise SerialException(\"could not open port %s: %s\" % (self.portstr, msg))\n\n        self._reconfigurePort()\n        self._port_handle.Open()\n        self._isOpen = True\n        if not self._rtscts:\n            self.setRTS(True)\n            self.setDTR(True)\n        self.flushInput()\n        self.flushOutput()\n\n    def _reconfigurePort(self):\n        \"\"\"Set communication parameters on opened port.\"\"\"\n        if not self._port_handle:\n            raise SerialException(\"Can only operate on a valid port handle\")\n\n        #~ self._port_handle.ReceivedBytesThreshold = 1\n\n        if self._timeout is None:\n            self._port_handle.ReadTimeout = System.IO.Ports.SerialPort.InfiniteTimeout\n        else:\n            self._port_handle.ReadTimeout = int(self._timeout*1000)\n\n        # if self._timeout != 0 and self._interCharTimeout is not None:\n            # timeouts = (int(self._interCharTimeout * 1000),) + timeouts[1:]\n\n        if self._writeTimeout is None:\n            self._port_handle.WriteTimeout = System.IO.Ports.SerialPort.InfiniteTimeout\n        else:\n            self._port_handle.WriteTimeout = int(self._writeTimeout*1000)\n\n\n        # Setup the connection info.\n        try:\n            self._port_handle.BaudRate = self._baudrate\n        except IOError, e:\n            # catch errors from illegal baudrate settings\n            raise ValueError(str(e))\n\n        if self._bytesize == FIVEBITS:\n            self._port_handle.DataBits     = 5\n        elif self._bytesize == SIXBITS:\n            self._port_handle.DataBits     = 6\n        elif self._bytesize == SEVENBITS:\n            self._port_handle.DataBits     = 7\n        elif self._bytesize == EIGHTBITS:\n            self._port_handle.DataBits     = 8\n        else:\n            raise ValueError(\"Unsupported number of data bits: %r\" % self._bytesize)\n\n        if self._parity == PARITY_NONE:\n            self._port_handle.Parity       = getattr(System.IO.Ports.Parity, 'None') # reserved keyword in Py3k\n        elif self._parity == PARITY_EVEN:\n            self._port_handle.Parity       = System.IO.Ports.Parity.Even\n        elif self._parity == PARITY_ODD:\n            self._port_handle.Parity       = System.IO.Ports.Parity.Odd\n        elif self._parity == PARITY_MARK:\n            self._port_handle.Parity       = System.IO.Ports.Parity.Mark\n        elif self._parity == PARITY_SPACE:\n            self._port_handle.Parity       = System.IO.Ports.Parity.Space\n        else:\n            raise ValueError(\"Unsupported parity mode: %r\" % self._parity)\n\n        if self._stopbits == STOPBITS_ONE:\n            self._port_handle.StopBits     = System.IO.Ports.StopBits.One\n        elif self._stopbits == STOPBITS_ONE_POINT_FIVE:\n            self._port_handle.StopBits     = System.IO.Ports.StopBits.OnePointFive\n        elif self._stopbits == STOPBITS_TWO:\n            self._port_handle.StopBits     = System.IO.Ports.StopBits.Two\n        else:\n            raise ValueError(\"Unsupported number of stop bits: %r\" % self._stopbits)\n\n        if self._rtscts and self._xonxoff:\n            self._port_handle.Handshake  = System.IO.Ports.Handshake.RequestToSendXOnXOff\n        elif self._rtscts:\n            self._port_handle.Handshake  = System.IO.Ports.Handshake.RequestToSend\n        elif self._xonxoff:\n            self._port_handle.Handshake  = System.IO.Ports.Handshake.XOnXOff\n        else:\n            self._port_handle.Handshake  = getattr(System.IO.Ports.Handshake, 'None')   # reserved keyword in Py3k\n\n    #~ def __del__(self):\n        #~ self.close()\n\n    def close(self):\n        \"\"\"Close port\"\"\"\n        if self._isOpen:\n            if self._port_handle:\n                try:\n                    self._port_handle.Close()\n                except System.IO.Ports.InvalidOperationException:\n                    # ignore errors. can happen for unplugged USB serial devices\n                    pass\n                self._port_handle = None\n            self._isOpen = False\n\n    def makeDeviceName(self, port):\n        try:\n            return device(port)\n        except TypeError, e:\n            raise SerialException(str(e))\n\n    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n\n    def inWaiting(self):\n        \"\"\"Return the number of characters currently in the input buffer.\"\"\"\n        if not self._port_handle: raise portNotOpenError\n        return self._port_handle.BytesToRead\n\n    def read(self, size=1):\n        \"\"\"Read size bytes from the serial port. If a timeout is set it may\n           return less characters as requested. With no timeout it will block\n           until the requested number of bytes is read.\"\"\"\n        if not self._port_handle: raise portNotOpenError\n        # must use single byte reads as this is the only way to read\n        # without applying encodings\n        data = bytearray()\n        while size:\n            try:\n                data.append(self._port_handle.ReadByte())\n            except System.TimeoutException, e:\n                break\n            else:\n                size -= 1\n        return bytes(data)\n\n    def write(self, data):\n        \"\"\"Output the given string over the serial port.\"\"\"\n        if not self._port_handle: raise portNotOpenError\n        if not isinstance(data, (bytes, bytearray)):\n            raise TypeError('expected %s or bytearray, got %s' % (bytes, type(data)))\n        try:\n            # must call overloaded method with byte array argument\n            # as this is the only one not applying encodings\n            self._port_handle.Write(as_byte_array(data), 0, len(data))\n        except System.TimeoutException, e:\n            raise writeTimeoutError\n        return len(data)\n\n    def flushInput(self):\n        \"\"\"Clear input buffer, discarding all that is in the buffer.\"\"\"\n        if not self._port_handle: raise portNotOpenError\n        self._port_handle.DiscardInBuffer()\n\n    def flushOutput(self):\n        \"\"\"Clear output buffer, aborting the current output and\n        discarding all that is in the buffer.\"\"\"\n        if not self._port_handle: raise portNotOpenError\n        self._port_handle.DiscardOutBuffer()\n\n    def sendBreak(self, duration=0.25):\n        \"\"\"Send break condition. Timed, returns to idle state after given duration.\"\"\"\n        if not self._port_handle: raise portNotOpenError\n        import time\n        self._port_handle.BreakState = True\n        time.sleep(duration)\n        self._port_handle.BreakState = False\n\n    def setBreak(self, level=True):\n        \"\"\"Set break: Controls TXD. When active, to transmitting is possible.\"\"\"\n        if not self._port_handle: raise portNotOpenError\n        self._port_handle.BreakState = bool(level)\n\n    def setRTS(self, level=True):\n        \"\"\"Set terminal status line: Request To Send\"\"\"\n        if not self._port_handle: raise portNotOpenError\n        self._port_handle.RtsEnable = bool(level)\n\n    def setDTR(self, level=True):\n        \"\"\"Set terminal status line: Data Terminal Ready\"\"\"\n        if not self._port_handle: raise portNotOpenError\n        self._port_handle.DtrEnable = bool(level)\n\n    def getCTS(self):\n        \"\"\"Read terminal status line: Clear To Send\"\"\"\n        if not self._port_handle: raise portNotOpenError\n        return self._port_handle.CtsHolding\n\n    def getDSR(self):\n        \"\"\"Read terminal status line: Data Set Ready\"\"\"\n        if not self._port_handle: raise portNotOpenError\n        return self._port_handle.DsrHolding\n\n    def getRI(self):\n        \"\"\"Read terminal status line: Ring Indicator\"\"\"\n        if not self._port_handle: raise portNotOpenError\n        #~ return self._port_handle.XXX\n        return False #XXX an error would be better\n\n    def getCD(self):\n        \"\"\"Read terminal status line: Carrier Detect\"\"\"\n        if not self._port_handle: raise portNotOpenError\n        return self._port_handle.CDHolding\n\n    # - - platform specific - - - -\n    # none\n\n\n# assemble Serial class with the platform specific implementation and the base\n# for file-like behavior. for Python 2.6 and newer, that provide the new I/O\n# library, derive from io.RawIOBase\ntry:\n    import io\nexcept ImportError:\n    # classic version with our own file-like emulation\n    class Serial(IronSerial, FileLike):\n        pass\nelse:\n    # io library present\n    class Serial(IronSerial, io.RawIOBase):\n        pass\n\n\n# Nur Testfunktion!!\nif __name__ == '__main__':\n    import sys\n\n    s = Serial(0)\n    sys.stdio.write('%s\\n' % s)\n\n    s = Serial()\n    sys.stdio.write('%s\\n' % s)\n\n\n    s.baudrate = 19200\n    s.databits = 7\n    s.close()\n    s.port = 0\n    s.open()\n    sys.stdio.write('%s\\n' % s)\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/serialjava.py",
    "content": "#!jython\n#\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# module for serial IO for Jython and JavaComm\n# see __init__.py\n#\n# (C) 2002-2008 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n\nfrom serial.serialutil import *\n\ndef my_import(name):\n    mod = __import__(name)\n    components = name.split('.')\n    for comp in components[1:]:\n        mod = getattr(mod, comp)\n    return mod\n\n\ndef detect_java_comm(names):\n    \"\"\"try given list of modules and return that imports\"\"\"\n    for name in names:\n        try:\n            mod = my_import(name)\n            mod.SerialPort\n            return mod\n        except (ImportError, AttributeError):\n            pass\n    raise ImportError(\"No Java Communications API implementation found\")\n\n\n# Java Communications API implementations\n# http://mho.republika.pl/java/comm/\n\ncomm = detect_java_comm([\n    'javax.comm', # Sun/IBM\n    'gnu.io',     # RXTX\n])\n\n\ndef device(portnumber):\n    \"\"\"Turn a port number into a device name\"\"\"\n    enum = comm.CommPortIdentifier.getPortIdentifiers()\n    ports = []\n    while enum.hasMoreElements():\n        el = enum.nextElement()\n        if el.getPortType() == comm.CommPortIdentifier.PORT_SERIAL:\n            ports.append(el)\n    return ports[portnumber].getName()\n\n\nclass JavaSerial(SerialBase):\n    \"\"\"Serial port class, implemented with Java Communications API and\n       thus usable with jython and the appropriate java extension.\"\"\"\n\n    def open(self):\n        \"\"\"Open port with current settings. This may throw a SerialException\n           if the port cannot be opened.\"\"\"\n        if self._port is None:\n            raise SerialException(\"Port must be configured before it can be used.\")\n        if self._isOpen:\n            raise SerialException(\"Port is already open.\")\n        if type(self._port) == type(''):      # strings are taken directly\n            portId = comm.CommPortIdentifier.getPortIdentifier(self._port)\n        else:\n            portId = comm.CommPortIdentifier.getPortIdentifier(device(self._port))     # numbers are transformed to a comport id obj\n        try:\n            self.sPort = portId.open(\"python serial module\", 10)\n        except Exception, msg:\n            self.sPort = None\n            raise SerialException(\"Could not open port: %s\" % msg)\n        self._reconfigurePort()\n        self._instream = self.sPort.getInputStream()\n        self._outstream = self.sPort.getOutputStream()\n        self._isOpen = True\n\n    def _reconfigurePort(self):\n        \"\"\"Set communication parameters on opened port.\"\"\"\n        if not self.sPort:\n            raise SerialException(\"Can only operate on a valid port handle\")\n\n        self.sPort.enableReceiveTimeout(30)\n        if self._bytesize == FIVEBITS:\n            jdatabits = comm.SerialPort.DATABITS_5\n        elif self._bytesize == SIXBITS:\n            jdatabits = comm.SerialPort.DATABITS_6\n        elif self._bytesize == SEVENBITS:\n            jdatabits = comm.SerialPort.DATABITS_7\n        elif self._bytesize == EIGHTBITS:\n            jdatabits = comm.SerialPort.DATABITS_8\n        else:\n            raise ValueError(\"unsupported bytesize: %r\" % self._bytesize)\n\n        if self._stopbits == STOPBITS_ONE:\n            jstopbits = comm.SerialPort.STOPBITS_1\n        elif stopbits == STOPBITS_ONE_POINT_FIVE:\n            self._jstopbits = comm.SerialPort.STOPBITS_1_5\n        elif self._stopbits == STOPBITS_TWO:\n            jstopbits = comm.SerialPort.STOPBITS_2\n        else:\n            raise ValueError(\"unsupported number of stopbits: %r\" % self._stopbits)\n\n        if self._parity == PARITY_NONE:\n            jparity = comm.SerialPort.PARITY_NONE\n        elif self._parity == PARITY_EVEN:\n            jparity = comm.SerialPort.PARITY_EVEN\n        elif self._parity == PARITY_ODD:\n            jparity = comm.SerialPort.PARITY_ODD\n        elif self._parity == PARITY_MARK:\n            jparity = comm.SerialPort.PARITY_MARK\n        elif self._parity == PARITY_SPACE:\n            jparity = comm.SerialPort.PARITY_SPACE\n        else:\n            raise ValueError(\"unsupported parity type: %r\" % self._parity)\n\n        jflowin = jflowout = 0\n        if self._rtscts:\n            jflowin  |=  comm.SerialPort.FLOWCONTROL_RTSCTS_IN\n            jflowout |=  comm.SerialPort.FLOWCONTROL_RTSCTS_OUT\n        if self._xonxoff:\n            jflowin  |=  comm.SerialPort.FLOWCONTROL_XONXOFF_IN\n            jflowout |=  comm.SerialPort.FLOWCONTROL_XONXOFF_OUT\n\n        self.sPort.setSerialPortParams(self._baudrate, jdatabits, jstopbits, jparity)\n        self.sPort.setFlowControlMode(jflowin | jflowout)\n\n        if self._timeout >= 0:\n            self.sPort.enableReceiveTimeout(self._timeout*1000)\n        else:\n            self.sPort.disableReceiveTimeout()\n\n    def close(self):\n        \"\"\"Close port\"\"\"\n        if self._isOpen:\n            if self.sPort:\n                self._instream.close()\n                self._outstream.close()\n                self.sPort.close()\n                self.sPort = None\n            self._isOpen = False\n\n    def makeDeviceName(self, port):\n        return device(port)\n\n    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n\n    def inWaiting(self):\n        \"\"\"Return the number of characters currently in the input buffer.\"\"\"\n        if not self.sPort: raise portNotOpenError\n        return self._instream.available()\n\n    def read(self, size=1):\n        \"\"\"Read size bytes from the serial port. If a timeout is set it may\n           return less characters as requested. With no timeout it will block\n           until the requested number of bytes is read.\"\"\"\n        if not self.sPort: raise portNotOpenError\n        read = bytearray()\n        if size > 0:\n            while len(read) < size:\n                x = self._instream.read()\n                if x == -1:\n                    if self.timeout >= 0:\n                        break\n                else:\n                    read.append(x)\n        return bytes(read)\n\n    def write(self, data):\n        \"\"\"Output the given string over the serial port.\"\"\"\n        if not self.sPort: raise portNotOpenError\n        if not isinstance(data, (bytes, bytearray)):\n            raise TypeError('expected %s or bytearray, got %s' % (bytes, type(data)))\n        self._outstream.write(data)\n        return len(data)\n\n    def flushInput(self):\n        \"\"\"Clear input buffer, discarding all that is in the buffer.\"\"\"\n        if not self.sPort: raise portNotOpenError\n        self._instream.skip(self._instream.available())\n\n    def flushOutput(self):\n        \"\"\"Clear output buffer, aborting the current output and\n        discarding all that is in the buffer.\"\"\"\n        if not self.sPort: raise portNotOpenError\n        self._outstream.flush()\n\n    def sendBreak(self, duration=0.25):\n        \"\"\"Send break condition. Timed, returns to idle state after given duration.\"\"\"\n        if not self.sPort: raise portNotOpenError\n        self.sPort.sendBreak(duration*1000.0)\n\n    def setBreak(self, level=1):\n        \"\"\"Set break: Controls TXD. When active, to transmitting is possible.\"\"\"\n        if self.fd is None: raise portNotOpenError\n        raise SerialException(\"The setBreak function is not implemented in java.\")\n\n    def setRTS(self, level=1):\n        \"\"\"Set terminal status line: Request To Send\"\"\"\n        if not self.sPort: raise portNotOpenError\n        self.sPort.setRTS(level)\n\n    def setDTR(self, level=1):\n        \"\"\"Set terminal status line: Data Terminal Ready\"\"\"\n        if not self.sPort: raise portNotOpenError\n        self.sPort.setDTR(level)\n\n    def getCTS(self):\n        \"\"\"Read terminal status line: Clear To Send\"\"\"\n        if not self.sPort: raise portNotOpenError\n        self.sPort.isCTS()\n\n    def getDSR(self):\n        \"\"\"Read terminal status line: Data Set Ready\"\"\"\n        if not self.sPort: raise portNotOpenError\n        self.sPort.isDSR()\n\n    def getRI(self):\n        \"\"\"Read terminal status line: Ring Indicator\"\"\"\n        if not self.sPort: raise portNotOpenError\n        self.sPort.isRI()\n\n    def getCD(self):\n        \"\"\"Read terminal status line: Carrier Detect\"\"\"\n        if not self.sPort: raise portNotOpenError\n        self.sPort.isCD()\n\n\n# assemble Serial class with the platform specific implementation and the base\n# for file-like behavior. for Python 2.6 and newer, that provide the new I/O\n# library, derive from io.RawIOBase\ntry:\n    import io\nexcept ImportError:\n    # classic version with our own file-like emulation\n    class Serial(JavaSerial, FileLike):\n        pass\nelse:\n    # io library present\n    class Serial(JavaSerial, io.RawIOBase):\n        pass\n\n\nif __name__ == '__main__':\n    s = Serial(0,\n         baudrate=19200,        # baudrate\n         bytesize=EIGHTBITS,    # number of databits\n         parity=PARITY_EVEN,    # enable parity checking\n         stopbits=STOPBITS_ONE, # number of stopbits\n         timeout=3,             # set a timeout value, None for waiting forever\n         xonxoff=0,             # enable software flow control\n         rtscts=0,              # enable RTS/CTS flow control\n    )\n    s.setRTS(1)\n    s.setDTR(1)\n    s.flushInput()\n    s.flushOutput()\n    s.write('hello')\n    sys.stdio.write('%r\\n' % s.read(5))\n    sys.stdio.write('%s\\n' % s.inWaiting())\n    del s\n\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/serialposix.py",
    "content": "#!/usr/bin/env python\n#\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# module for serial IO for POSIX compatible systems, like Linux\n# see __init__.py\n#\n# (C) 2001-2010 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n#\n# parts based on code from Grant B. Edwards  <grante@visi.com>:\n#  ftp://ftp.visi.com/users/grante/python/PosixSerial.py\n#\n# references: http://www.easysw.com/~mike/serial/serial.html\n\nimport sys, os, fcntl, termios, struct, select, errno, time\nfrom serial.serialutil import *\n\n# Do check the Python version as some constants have moved.\nif (sys.hexversion < 0x020100f0):\n    import TERMIOS\nelse:\n    TERMIOS = termios\n\nif (sys.hexversion < 0x020200f0):\n    import FCNTL\nelse:\n    FCNTL = fcntl\n\n# try to detect the OS so that a device can be selected...\n# this code block should supply a device() and set_special_baudrate() function\n# for the platform\nplat = sys.platform.lower()\n\nif   plat[:5] == 'linux':    # Linux (confirmed)\n\n    def device(port):\n        return '/dev/ttyS%d' % port\n\n    ASYNC_SPD_MASK = 0x1030\n    ASYNC_SPD_CUST = 0x0030\n\n    def set_special_baudrate(port, baudrate):\n        import array\n        buf = array.array('i', [0] * 32)\n\n        # get serial_struct\n        FCNTL.ioctl(port.fd, TERMIOS.TIOCGSERIAL, buf)\n\n        # set custom divisor\n        buf[6] = buf[7] / baudrate\n\n        # update flags\n        buf[4] &= ~ASYNC_SPD_MASK\n        buf[4] |= ASYNC_SPD_CUST\n\n        # set serial_struct\n        try:\n            res = FCNTL.ioctl(port.fd, TERMIOS.TIOCSSERIAL, buf)\n        except IOError:\n            raise ValueError('Failed to set custom baud rate: %r' % baudrate)\n\n    baudrate_constants = {\n        0:       0000000,  # hang up\n        50:      0000001,\n        75:      0000002,\n        110:     0000003,\n        134:     0000004,\n        150:     0000005,\n        200:     0000006,\n        300:     0000007,\n        600:     0000010,\n        1200:    0000011,\n        1800:    0000012,\n        2400:    0000013,\n        4800:    0000014,\n        9600:    0000015,\n        19200:   0000016,\n        38400:   0000017,\n        57600:   0010001,\n        115200:  0010002,\n        230400:  0010003,\n        460800:  0010004,\n        500000:  0010005,\n        576000:  0010006,\n        921600:  0010007,\n        1000000: 0010010,\n        1152000: 0010011,\n        1500000: 0010012,\n        2000000: 0010013,\n        2500000: 0010014,\n        3000000: 0010015,\n        3500000: 0010016,\n        4000000: 0010017\n    }\n\nelif plat == 'cygwin':       # cygwin/win32 (confirmed)\n\n    def device(port):\n        return '/dev/com%d' % (port + 1)\n\n    def set_special_baudrate(port, baudrate):\n        raise ValueError(\"sorry don't know how to handle non standard baud rate on this platform\")\n\n    baudrate_constants = {}\n\nelif plat == 'openbsd3':    # BSD (confirmed)\n\n    def device(port):\n        return '/dev/ttyp%d' % port\n\n    def set_special_baudrate(port, baudrate):\n        raise ValueError(\"sorry don't know how to handle non standard baud rate on this platform\")\n\n    baudrate_constants = {}\n\nelif plat[:3] == 'bsd' or  \\\n     plat[:7] == 'freebsd' or \\\n     plat[:7] == 'openbsd':  # BSD (confirmed for freebsd4: cuaa%d)\n\n    def device(port):\n        return '/dev/cuad%d' % port\n\n    def set_special_baudrate(port, baudrate):\n        raise ValueError(\"sorry don't know how to handle non standard baud rate on this platform\")\n\n    baudrate_constants = {}\n\nelif plat[:6] == 'darwin':   # OS X\n\n    version = os.uname()[2].split('.')\n    # Tiger or above can support arbitrary serial speeds\n    if int(version[0]) >= 8:\n        def set_special_baudrate(port, baudrate):\n            # use IOKit-specific call to set up high speeds\n            import array, fcntl\n            buf = array.array('i', [baudrate])\n            IOSSIOSPEED = 0x80045402 #_IOW('T', 2, speed_t)\n            fcntl.ioctl(port.fd, IOSSIOSPEED, buf, 1)\n    else: # version < 8\n        def set_special_baudrate(port, baudrate):\n            raise ValueError(\"baud rate not supported\")\n\n    def device(port):\n        return '/dev/cuad%d' % port\n\n    baudrate_constants = {}\n\n\nelif plat[:6] == 'netbsd':   # NetBSD 1.6 testing by Erk\n\n    def device(port):\n        return '/dev/dty%02d' % port\n\n    def set_special_baudrate(port, baudrate):\n        raise ValueError(\"sorry don't know how to handle non standard baud rate on this platform\")\n\n    baudrate_constants = {}\n\nelif plat[:4] == 'irix':     # IRIX (partially tested)\n\n    def device(port):\n        return '/dev/ttyf%d' % (port+1) #XXX different device names depending on flow control\n\n    def set_special_baudrate(port, baudrate):\n        raise ValueError(\"sorry don't know how to handle non standard baud rate on this platform\")\n\n    baudrate_constants = {}\n\nelif plat[:2] == 'hp':       # HP-UX (not tested)\n\n    def device(port):\n        return '/dev/tty%dp0' % (port+1)\n\n    def set_special_baudrate(port, baudrate):\n        raise ValueError(\"sorry don't know how to handle non standard baud rate on this platform\")\n\n    baudrate_constants = {}\n\nelif plat[:5] == 'sunos':    # Solaris/SunOS (confirmed)\n\n    def device(port):\n        return '/dev/tty%c' % (ord('a')+port)\n\n    def set_special_baudrate(port, baudrate):\n        raise ValueError(\"sorry don't know how to handle non standard baud rate on this platform\")\n\n    baudrate_constants = {}\n\nelif plat[:3] == 'aix':      # AIX\n\n    def device(port):\n        return '/dev/tty%d' % (port)\n\n    def set_special_baudrate(port, baudrate):\n        raise ValueError(\"sorry don't know how to handle non standard baud rate on this platform\")\n\n    baudrate_constants = {}\n\nelse:\n    # platform detection has failed...\n    sys.stderr.write(\"\"\"\\\ndon't know how to number ttys on this system.\n! Use an explicit path (eg /dev/ttyS1) or send this information to\n! the author of this module:\n\nsys.platform = %r\nos.name = %r\nserialposix.py version = %s\n\nalso add the device name of the serial port and where the\ncounting starts for the first serial port.\ne.g. 'first serial port: /dev/ttyS0'\nand with a bit luck you can get this module running...\n\"\"\" % (sys.platform, os.name, VERSION))\n    # no exception, just continue with a brave attempt to build a device name\n    # even if the device name is not correct for the platform it has chances\n    # to work using a string with the real device name as port parameter.\n    def device(portum):\n        return '/dev/ttyS%d' % portnum\n    def set_special_baudrate(port, baudrate):\n        raise SerialException(\"sorry don't know how to handle non standard baud rate on this platform\")\n    baudrate_constants = {}\n    #~ raise Exception, \"this module does not run on this platform, sorry.\"\n\n# whats up with \"aix\", \"beos\", ....\n# they should work, just need to know the device names.\n\n\n# load some constants for later use.\n# try to use values from TERMIOS, use defaults from linux otherwise\nTIOCMGET  = hasattr(TERMIOS, 'TIOCMGET') and TERMIOS.TIOCMGET or 0x5415\nTIOCMBIS  = hasattr(TERMIOS, 'TIOCMBIS') and TERMIOS.TIOCMBIS or 0x5416\nTIOCMBIC  = hasattr(TERMIOS, 'TIOCMBIC') and TERMIOS.TIOCMBIC or 0x5417\nTIOCMSET  = hasattr(TERMIOS, 'TIOCMSET') and TERMIOS.TIOCMSET or 0x5418\n\n#TIOCM_LE = hasattr(TERMIOS, 'TIOCM_LE') and TERMIOS.TIOCM_LE or 0x001\nTIOCM_DTR = hasattr(TERMIOS, 'TIOCM_DTR') and TERMIOS.TIOCM_DTR or 0x002\nTIOCM_RTS = hasattr(TERMIOS, 'TIOCM_RTS') and TERMIOS.TIOCM_RTS or 0x004\n#TIOCM_ST = hasattr(TERMIOS, 'TIOCM_ST') and TERMIOS.TIOCM_ST or 0x008\n#TIOCM_SR = hasattr(TERMIOS, 'TIOCM_SR') and TERMIOS.TIOCM_SR or 0x010\n\nTIOCM_CTS = hasattr(TERMIOS, 'TIOCM_CTS') and TERMIOS.TIOCM_CTS or 0x020\nTIOCM_CAR = hasattr(TERMIOS, 'TIOCM_CAR') and TERMIOS.TIOCM_CAR or 0x040\nTIOCM_RNG = hasattr(TERMIOS, 'TIOCM_RNG') and TERMIOS.TIOCM_RNG or 0x080\nTIOCM_DSR = hasattr(TERMIOS, 'TIOCM_DSR') and TERMIOS.TIOCM_DSR or 0x100\nTIOCM_CD  = hasattr(TERMIOS, 'TIOCM_CD') and TERMIOS.TIOCM_CD or TIOCM_CAR\nTIOCM_RI  = hasattr(TERMIOS, 'TIOCM_RI') and TERMIOS.TIOCM_RI or TIOCM_RNG\n#TIOCM_OUT1 = hasattr(TERMIOS, 'TIOCM_OUT1') and TERMIOS.TIOCM_OUT1 or 0x2000\n#TIOCM_OUT2 = hasattr(TERMIOS, 'TIOCM_OUT2') and TERMIOS.TIOCM_OUT2 or 0x4000\nTIOCINQ   = hasattr(TERMIOS, 'FIONREAD') and TERMIOS.FIONREAD or 0x541B\n\nTIOCM_zero_str = struct.pack('I', 0)\nTIOCM_RTS_str = struct.pack('I', TIOCM_RTS)\nTIOCM_DTR_str = struct.pack('I', TIOCM_DTR)\n\nTIOCSBRK  = hasattr(TERMIOS, 'TIOCSBRK') and TERMIOS.TIOCSBRK or 0x5427\nTIOCCBRK  = hasattr(TERMIOS, 'TIOCCBRK') and TERMIOS.TIOCCBRK or 0x5428\n\n\nclass PosixSerial(SerialBase):\n    \"\"\"Serial port class POSIX implementation. Serial port configuration is \n    done with termios and fcntl. Runs on Linux and many other Un*x like\n    systems.\"\"\"\n\n    def open(self):\n        \"\"\"Open port with current settings. This may throw a SerialException\n           if the port cannot be opened.\"\"\"\n        if self._port is None:\n            raise SerialException(\"Port must be configured before it can be used.\")\n        if self._isOpen:\n            raise SerialException(\"Port is already open.\")\n        self.fd = None\n        # open\n        try:\n            self.fd = os.open(self.portstr, os.O_RDWR|os.O_NOCTTY|os.O_NONBLOCK)\n        except Exception, msg:\n            self.fd = None\n            raise SerialException(\"could not open port %s: %s\" % (self._port, msg))\n        #~ fcntl.fcntl(self.fd, FCNTL.F_SETFL, 0)  # set blocking\n\n        try:\n            self._reconfigurePort()\n        except:\n            try:\n                os.close(self.fd)\n            except:\n                # ignore any exception when closing the port\n                # also to keep original exception that happened when setting up\n                pass\n            self.fd = None\n            raise\n        else:\n            self._isOpen = True\n        #~ self.flushInput()\n\n\n    def _reconfigurePort(self):\n        \"\"\"Set communication parameters on opened port.\"\"\"\n        if self.fd is None:\n            raise SerialException(\"Can only operate on a valid file descriptor\")\n        custom_baud = None\n\n        vmin = vtime = 0                # timeout is done via select\n        if self._interCharTimeout is not None:\n            vmin = 1\n            vtime = int(self._interCharTimeout * 10)\n        try:\n            orig_attr = termios.tcgetattr(self.fd)\n            iflag, oflag, cflag, lflag, ispeed, ospeed, cc = orig_attr\n        except termios.error, msg:      # if a port is nonexistent but has a /dev file, it'll fail here\n            raise SerialException(\"Could not configure port: %s\" % msg)\n        # set up raw mode / no echo / binary\n        cflag |=  (TERMIOS.CLOCAL|TERMIOS.CREAD)\n        lflag &= ~(TERMIOS.ICANON|TERMIOS.ECHO|TERMIOS.ECHOE|TERMIOS.ECHOK|TERMIOS.ECHONL|\n                     TERMIOS.ISIG|TERMIOS.IEXTEN) #|TERMIOS.ECHOPRT\n        for flag in ('ECHOCTL', 'ECHOKE'): # netbsd workaround for Erk\n            if hasattr(TERMIOS, flag):\n                lflag &= ~getattr(TERMIOS, flag)\n\n        oflag &= ~(TERMIOS.OPOST)\n        iflag &= ~(TERMIOS.INLCR|TERMIOS.IGNCR|TERMIOS.ICRNL|TERMIOS.IGNBRK)\n        if hasattr(TERMIOS, 'IUCLC'):\n            iflag &= ~TERMIOS.IUCLC\n        if hasattr(TERMIOS, 'PARMRK'):\n            iflag &= ~TERMIOS.PARMRK\n\n        # setup baud rate\n        try:\n            ispeed = ospeed = getattr(TERMIOS, 'B%s' % (self._baudrate))\n        except AttributeError:\n            try:\n                ispeed = ospeed = baudrate_constants[self._baudrate]\n            except KeyError:\n                #~ raise ValueError('Invalid baud rate: %r' % self._baudrate)\n                # may need custom baud rate, it isn't in our list.\n                ispeed = ospeed = getattr(TERMIOS, 'B38400')\n                try:\n                    custom_baud = int(self._baudrate) # store for later\n                except ValueError:\n                    raise ValueError('Invalid baud rate: %r' % self._baudrate)\n                else:\n                    if custom_baud < 0:\n                        raise ValueError('Invalid baud rate: %r' % self._baudrate)\n\n        # setup char len\n        cflag &= ~TERMIOS.CSIZE\n        if self._bytesize == 8:\n            cflag |= TERMIOS.CS8\n        elif self._bytesize == 7:\n            cflag |= TERMIOS.CS7\n        elif self._bytesize == 6:\n            cflag |= TERMIOS.CS6\n        elif self._bytesize == 5:\n            cflag |= TERMIOS.CS5\n        else:\n            raise ValueError('Invalid char len: %r' % self._bytesize)\n        # setup stopbits\n        if self._stopbits == STOPBITS_ONE:\n            cflag &= ~(TERMIOS.CSTOPB)\n        elif self._stopbits == STOPBITS_ONE_POINT_FIVE:\n            cflag |=  (TERMIOS.CSTOPB)  # XXX same as TWO.. there is no POSIX support for 1.5\n        elif self._stopbits == STOPBITS_TWO:\n            cflag |=  (TERMIOS.CSTOPB)\n        else:\n            raise ValueError('Invalid stop bit specification: %r' % self._stopbits)\n        # setup parity\n        iflag &= ~(TERMIOS.INPCK|TERMIOS.ISTRIP)\n        if self._parity == PARITY_NONE:\n            cflag &= ~(TERMIOS.PARENB|TERMIOS.PARODD)\n        elif self._parity == PARITY_EVEN:\n            cflag &= ~(TERMIOS.PARODD)\n            cflag |=  (TERMIOS.PARENB)\n        elif self._parity == PARITY_ODD:\n            cflag |=  (TERMIOS.PARENB|TERMIOS.PARODD)\n        else:\n            raise ValueError('Invalid parity: %r' % self._parity)\n        # setup flow control\n        # xonxoff\n        if hasattr(TERMIOS, 'IXANY'):\n            if self._xonxoff:\n                iflag |=  (TERMIOS.IXON|TERMIOS.IXOFF) #|TERMIOS.IXANY)\n            else:\n                iflag &= ~(TERMIOS.IXON|TERMIOS.IXOFF|TERMIOS.IXANY)\n        else:\n            if self._xonxoff:\n                iflag |=  (TERMIOS.IXON|TERMIOS.IXOFF)\n            else:\n                iflag &= ~(TERMIOS.IXON|TERMIOS.IXOFF)\n        # rtscts\n        if hasattr(TERMIOS, 'CRTSCTS'):\n            if self._rtscts:\n                cflag |=  (TERMIOS.CRTSCTS)\n            else:\n                cflag &= ~(TERMIOS.CRTSCTS)\n        elif hasattr(TERMIOS, 'CNEW_RTSCTS'):   # try it with alternate constant name\n            if self._rtscts:\n                cflag |=  (TERMIOS.CNEW_RTSCTS)\n            else:\n                cflag &= ~(TERMIOS.CNEW_RTSCTS)\n        # XXX should there be a warning if setting up rtscts (and xonxoff etc) fails??\n\n        # buffer\n        # vmin \"minimal number of characters to be read. = for non blocking\"\n        if vmin < 0 or vmin > 255:\n            raise ValueError('Invalid vmin: %r ' % vmin)\n        cc[TERMIOS.VMIN] = vmin\n        # vtime\n        if vtime < 0 or vtime > 255:\n            raise ValueError('Invalid vtime: %r' % vtime)\n        cc[TERMIOS.VTIME] = vtime\n        # activate settings\n        if [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] != orig_attr:\n            termios.tcsetattr(self.fd, TERMIOS.TCSANOW, [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])\n\n        # apply custom baud rate, if any\n        if custom_baud is not None:\n            set_special_baudrate(self, custom_baud)\n\n    def close(self):\n        \"\"\"Close port\"\"\"\n        if self._isOpen:\n            if self.fd is not None:\n                os.close(self.fd)\n                self.fd = None\n            self._isOpen = False\n\n    def makeDeviceName(self, port):\n        return device(port)\n\n    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n\n    def inWaiting(self):\n        \"\"\"Return the number of characters currently in the input buffer.\"\"\"\n        #~ s = fcntl.ioctl(self.fd, TERMIOS.FIONREAD, TIOCM_zero_str)\n        s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)\n        return struct.unpack('I',s)[0]\n\n    # select based implementation, proved to work on many systems\n    def read(self, size=1):\n        \"\"\"Read size bytes from the serial port. If a timeout is set it may\n           return less characters as requested. With no timeout it will block\n           until the requested number of bytes is read.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        read = bytearray()\n        while len(read) < size:\n            ready,_,_ = select.select([self.fd],[],[], self._timeout)\n            # If select was used with a timeout, and the timeout occurs, it\n            # returns with empty lists -> thus abort read operation.\n            # For timeout == 0 (non-blocking operation) also abort when there\n            # is nothing to read.\n            if not ready:\n                break   # timeout\n            buf = os.read(self.fd, size-len(read))\n            # read should always return some data as select reported it was\n            # ready to read when we get to this point.\n            if not buf:\n                # Disconnected devices, at least on Linux, show the\n                # behavior that they are always ready to read immediately\n                # but reading returns nothing.\n                raise SerialException('device reports readiness to read but returned no data (device disconnected?)')\n            read.extend(buf)\n        return bytes(read)\n\n    def write(self, data):\n        \"\"\"Output the given string over the serial port.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        t = len(data)\n        d = data\n        if self._writeTimeout is not None and self._writeTimeout > 0:\n            timeout = time.time() + self._writeTimeout\n        else:\n            timeout = None\n        while t > 0:\n            try:\n                n = os.write(self.fd, d)\n                if timeout:\n                    # when timeout is set, use select to wait for being ready\n                    # with the time left as timeout\n                    timeleft = timeout - time.time()\n                    if timeleft < 0:\n                        raise writeTimeoutError\n                    _, ready, _ = select.select([], [self.fd], [], timeleft)\n                    if not ready:\n                        raise writeTimeoutError\n                d = d[n:]\n                t = t - n\n            except OSError, v:\n                if v.errno != errno.EAGAIN:\n                    raise SerialException('write failed: %s' % (v,))\n        return len(data)\n\n    def flush(self):\n        \"\"\"Flush of file like objects. In this case, wait until all data\n           is written.\"\"\"\n        self.drainOutput()\n\n    def flushInput(self):\n        \"\"\"Clear input buffer, discarding all that is in the buffer.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        termios.tcflush(self.fd, TERMIOS.TCIFLUSH)\n\n    def flushOutput(self):\n        \"\"\"Clear output buffer, aborting the current output and\n        discarding all that is in the buffer.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        termios.tcflush(self.fd, TERMIOS.TCOFLUSH)\n\n    def sendBreak(self, duration=0.25):\n        \"\"\"Send break condition. Timed, returns to idle state after given duration.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        termios.tcsendbreak(self.fd, int(duration/0.25))\n\n    def setBreak(self, level=1):\n        \"\"\"Set break: Controls TXD. When active, no transmitting is possible.\"\"\"\n        if self.fd is None: raise portNotOpenError\n        if level:\n            fcntl.ioctl(self.fd, TIOCSBRK)\n        else:\n            fcntl.ioctl(self.fd, TIOCCBRK)\n\n    def setRTS(self, level=1):\n        \"\"\"Set terminal status line: Request To Send\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if level:\n            fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_RTS_str)\n        else:\n            fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_RTS_str)\n\n    def setDTR(self, level=1):\n        \"\"\"Set terminal status line: Data Terminal Ready\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if level:\n            fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str)\n        else:\n            fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_DTR_str)\n\n    def getCTS(self):\n        \"\"\"Read terminal status line: Clear To Send\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)\n        return struct.unpack('I',s)[0] & TIOCM_CTS != 0\n\n    def getDSR(self):\n        \"\"\"Read terminal status line: Data Set Ready\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)\n        return struct.unpack('I',s)[0] & TIOCM_DSR != 0\n\n    def getRI(self):\n        \"\"\"Read terminal status line: Ring Indicator\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)\n        return struct.unpack('I',s)[0] & TIOCM_RI != 0\n\n    def getCD(self):\n        \"\"\"Read terminal status line: Carrier Detect\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str)\n        return struct.unpack('I',s)[0] & TIOCM_CD != 0\n\n    # - - platform specific - - - -\n\n    def drainOutput(self):\n        \"\"\"internal - not portable!\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        termios.tcdrain(self.fd)\n\n    def nonblocking(self):\n        \"\"\"internal - not portable!\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        fcntl.fcntl(self.fd, FCNTL.F_SETFL, os.O_NONBLOCK)\n\n    def fileno(self):\n        \"\"\"For easier use of the serial port instance with select.\n           WARNING: this function is not portable to different platforms!\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        return self.fd\n\n    def flowControl(self, enable):\n        \"\"\"manually control flow - when hardware or software flow control is\n        enabled\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if enable:\n            termios.tcflow(self.fd, TERMIOS.TCION)\n        else:\n            termios.tcflow(self.fd, TERMIOS.TCIOFF)\n\n\n# assemble Serial class with the platform specifc implementation and the base\n# for file-like behavior. for Python 2.6 and newer, that provide the new I/O\n# library, derrive from io.RawIOBase\ntry:\n    import io\nexcept ImportError:\n    # classic version with our own file-like emulation\n    class Serial(PosixSerial, FileLike):\n        pass\nelse:\n    # io library present\n    class Serial(PosixSerial, io.RawIOBase):\n        pass\n\nclass PosixPollSerial(Serial):\n    \"\"\"poll based read implementation. not all systems support poll properly.\n    however this one has better handling of errors, such as a device\n    disconnecting while it's in use (e.g. USB-serial unplugged)\"\"\"\n\n    def read(self, size=1):\n        \"\"\"Read size bytes from the serial port. If a timeout is set it may\n           return less characters as requested. With no timeout it will block\n           until the requested number of bytes is read.\"\"\"\n        if self.fd is None: raise portNotOpenError\n        read = bytearray()\n        poll = select.poll()\n        poll.register(self.fd, select.POLLIN|select.POLLERR|select.POLLHUP|select.POLLNVAL)\n        if size > 0:\n            while len(read) < size:\n                # print \"\\tread(): size\",size, \"have\", len(read)    #debug\n                # wait until device becomes ready to read (or something fails)\n                for fd, event in poll.poll(self._timeout*1000):\n                    if event & (select.POLLERR|select.POLLHUP|select.POLLNVAL):\n                        raise SerialException('device reports error (poll)')\n                    #  we don't care if it is select.POLLIN or timeout, that's\n                    #  handled below\n                buf = os.read(self.fd, size - len(read))\n                read.extend(buf)\n                if ((self._timeout is not None and self._timeout >= 0) or \n                    (self._interCharTimeout is not None and self._interCharTimeout > 0)) and not buf:\n                    break   # early abort on timeout\n        return bytes(read)\n\n\nif __name__ == '__main__':\n    s = Serial(0,\n                 baudrate=19200,        # baud rate\n                 bytesize=EIGHTBITS,    # number of data bits\n                 parity=PARITY_EVEN,    # enable parity checking\n                 stopbits=STOPBITS_ONE, # number of stop bits\n                 timeout=3,             # set a timeout value, None for waiting forever\n                 xonxoff=0,             # enable software flow control\n                 rtscts=0,              # enable RTS/CTS flow control\n               )\n    s.setRTS(1)\n    s.setDTR(1)\n    s.flushInput()\n    s.flushOutput()\n    s.write('hello')\n    sys.stdout.write('%r\\n' % s.read(5))\n    sys.stdout.write('%s\\n' % s.inWaiting())\n    del s\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/serialutil.py",
    "content": "#! python\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# see __init__.py\n#\n# (C) 2001-2010 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n\n# compatibility for older Python < 2.6\ntry:\n    bytes\n    bytearray\nexcept (NameError, AttributeError):\n    # Python older than 2.6 do not have these types. Like for Python 2.6 they\n    # should behave like str. For Python older than 3.0 we want to work with\n    # strings anyway, only later versions have a true bytes type.\n    bytes = str\n    # bytearray is a mutable type that is easily turned into an instance of\n    # bytes\n    class bytearray(list):\n        # for bytes(bytearray()) usage\n        def __str__(self): return ''.join(self)\n        def __repr__(self): return 'bytearray(%r)' % ''.join(self)\n        # append automatically converts integers to characters\n        def append(self, item):\n            if isinstance(item, str):\n                list.append(self, item)\n            else:\n                list.append(self, chr(item))\n        # +=\n        def __iadd__(self, other):\n            for byte in other:\n                self.append(byte)\n            return self\n\n        def __getslice__(self, i, j):\n            return bytearray(list.__getslice__(self, i, j))\n\n        def __getitem__(self, item):\n            if isinstance(item, slice):\n                return bytearray(list.__getitem__(self, item))\n            else:\n                return ord(list.__getitem__(self, item))\n\n        def __eq__(self, other):\n            if isinstance(other, basestring):\n                other = bytearray(other)\n            return list.__eq__(self, other)\n\n# all Python versions prior 3.x convert str([17]) to '[17]' instead of '\\x11'\n# so a simple bytes(sequence) doesn't work for all versions\ndef to_bytes(seq):\n    \"\"\"convert a sequence to a bytes type\"\"\"\n    b = bytearray()\n    for item in seq:\n        b.append(item)  # this one handles int and str\n    return bytes(b)\n\n# create control bytes\nXON  = to_bytes([17])\nXOFF = to_bytes([19])\n\nCR = to_bytes([13])\nLF = to_bytes([10])\n\n\nPARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE = 'N', 'E', 'O', 'M', 'S'\nSTOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO = (1, 1.5, 2)\nFIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5, 6, 7, 8)\n\nPARITY_NAMES = {\n    PARITY_NONE:  'None',\n    PARITY_EVEN:  'Even',\n    PARITY_ODD:   'Odd',\n    PARITY_MARK:  'Mark',\n    PARITY_SPACE: 'Space',\n}\n\n\nclass SerialException(IOError):\n    \"\"\"Base class for serial port related exceptions.\"\"\"\n\n\nclass SerialTimeoutException(SerialException):\n    \"\"\"Write timeouts give an exception\"\"\"\n\n\nwriteTimeoutError = SerialTimeoutException(\"Write timeout\")\nportNotOpenError = ValueError('Attempting to use a port that is not open')\n\n\nclass FileLike(object):\n    \"\"\"An abstract file like class.\n\n    This class implements readline and readlines based on read and\n    writelines based on write.\n    This class is used to provide the above functions for to Serial\n    port objects.\n\n    Note that when the serial port was opened with _NO_ timeout that\n    readline blocks until it sees a newline (or the specified size is\n    reached) and that readlines would never return and therefore\n    refuses to work (it raises an exception in this case)!\n    \"\"\"\n\n    def __init__(self):\n        self.closed = True\n\n    def close(self):\n        self.closed = True\n\n    # so that ports are closed when objects are discarded\n    def __del__(self):\n        \"\"\"Destructor.  Calls close().\"\"\"\n        # The try/except block is in case this is called at program\n        # exit time, when it's possible that globals have already been\n        # deleted, and then the close() call might fail.  Since\n        # there's nothing we can do about such failures and they annoy\n        # the end users, we suppress the traceback.\n        try:\n            self.close()\n        except:\n            pass\n\n    def writelines(self, sequence):\n        for line in sequence:\n            self.write(line)\n\n    def flush(self):\n        \"\"\"flush of file like objects\"\"\"\n        pass\n\n    # iterator for e.g. \"for line in Serial(0): ...\" usage\n    def next(self):\n        line = self.readline()\n        if not line: raise StopIteration\n        return line\n\n    def __iter__(self):\n        return self\n\n    def readline(self, size=None, eol=LF):\n        \"\"\"read a line which is terminated with end-of-line (eol) character\n        ('\\n' by default) or until timeout.\"\"\"\n        leneol = len(eol)\n        line = bytearray()\n        while True:\n            c = self.read(1)\n            if c:\n                line += c\n                if line[-leneol:] == eol:\n                    break\n                if size is not None and len(line) >= size:\n                    break\n            else:\n                break\n        return bytes(line)\n\n    def readlines(self, sizehint=None, eol=LF):\n        \"\"\"read a list of lines, until timeout.\n        sizehint is ignored.\"\"\"\n        if self.timeout is None:\n            raise ValueError(\"Serial port MUST have enabled timeout for this function!\")\n        leneol = len(eol)\n        lines = []\n        while True:\n            line = self.readline(eol=eol)\n            if line:\n                lines.append(line)\n                if line[-leneol:] != eol:    # was the line received with a timeout?\n                    break\n            else:\n                break\n        return lines\n\n    def xreadlines(self, sizehint=None):\n        \"\"\"Read lines, implemented as generator. It will raise StopIteration on\n        timeout (empty read). sizehint is ignored.\"\"\"\n        while True:\n            line = self.readline()\n            if not line: break\n            yield line\n\n    # other functions of file-likes - not used by pySerial\n\n    #~ readinto(b)\n\n    def seek(self, pos, whence=0):\n        raise IOError(\"file is not seekable\")\n\n    def tell(self):\n        raise IOError(\"file is not seekable\")\n\n    def truncate(self, n=None):\n        raise IOError(\"file is not seekable\")\n\n    def isatty(self):\n        return False\n\n\nclass SerialBase(object):\n    \"\"\"Serial port base class. Provides __init__ function and properties to\n       get/set port settings.\"\"\"\n\n    # default values, may be overridden in subclasses that do not support all values\n    BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,\n                 9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000,\n                 576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000,\n                 3000000, 3500000, 4000000)\n    BYTESIZES = (FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS)\n    PARITIES  = (PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE)\n    STOPBITS  = (STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO)\n\n    def __init__(self,\n                 port = None,           # number of device, numbering starts at\n                                        # zero. if everything fails, the user\n                                        # can specify a device string, note\n                                        # that this isn't portable anymore\n                                        # port will be opened if one is specified\n                 baudrate=9600,         # baud rate\n                 bytesize=EIGHTBITS,    # number of data bits\n                 parity=PARITY_NONE,    # enable parity checking\n                 stopbits=STOPBITS_ONE, # number of stop bits\n                 timeout=None,          # set a timeout value, None to wait forever\n                 xonxoff=False,         # enable software flow control\n                 rtscts=False,          # enable RTS/CTS flow control\n                 writeTimeout=None,     # set a timeout for writes\n                 dsrdtr=False,          # None: use rtscts setting, dsrdtr override if True or False\n                 interCharTimeout=None  # Inter-character timeout, None to disable\n                 ):\n        \"\"\"Initialize comm port object. If a port is given, then the port will be\n           opened immediately. Otherwise a Serial port object in closed state\n           is returned.\"\"\"\n\n        self._isOpen   = False\n        self._port     = None           # correct value is assigned below through properties\n        self._baudrate = None           # correct value is assigned below through properties\n        self._bytesize = None           # correct value is assigned below through properties\n        self._parity   = None           # correct value is assigned below through properties\n        self._stopbits = None           # correct value is assigned below through properties\n        self._timeout  = None           # correct value is assigned below through properties\n        self._writeTimeout = None       # correct value is assigned below through properties\n        self._xonxoff  = None           # correct value is assigned below through properties\n        self._rtscts   = None           # correct value is assigned below through properties\n        self._dsrdtr   = None           # correct value is assigned below through properties\n        self._interCharTimeout = None   # correct value is assigned below through properties\n\n        # assign values using get/set methods using the properties feature\n        self.port     = port\n        self.baudrate = baudrate\n        self.bytesize = bytesize\n        self.parity   = parity\n        self.stopbits = stopbits\n        self.timeout  = timeout\n        self.writeTimeout = writeTimeout\n        self.xonxoff  = xonxoff\n        self.rtscts   = rtscts\n        self.dsrdtr   = dsrdtr\n        self.interCharTimeout = interCharTimeout\n\n        if port is not None:\n            self.open()\n\n    def isOpen(self):\n        \"\"\"Check if the port is opened.\"\"\"\n        return self._isOpen\n\n    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n\n    # TODO: these are not really needed as the is the BAUDRATES etc. attribute...\n    # maybe i remove them before the final release...\n\n    def getSupportedBaudrates(self):\n        return [(str(b), b) for b in self.BAUDRATES]\n\n    def getSupportedByteSizes(self):\n        return [(str(b), b) for b in self.BYTESIZES]\n\n    def getSupportedStopbits(self):\n        return [(str(b), b) for b in self.STOPBITS]\n\n    def getSupportedParities(self):\n        return [(PARITY_NAMES[b], b) for b in self.PARITIES]\n\n    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n\n    def setPort(self, port):\n        \"\"\"Change the port. The attribute portstr is set to a string that\n           contains the name of the port.\"\"\"\n\n        was_open = self._isOpen\n        if was_open: self.close()\n        if port is not None:\n            if isinstance(port, basestring):\n                self.portstr = port\n            else:\n                self.portstr = self.makeDeviceName(port)\n        else:\n            self.portstr = None\n        self._port = port\n        self.name = self.portstr\n        if was_open: self.open()\n\n    def getPort(self):\n        \"\"\"Get the current port setting. The value that was passed on init or using\n           setPort() is passed back. See also the attribute portstr which contains\n           the name of the port as a string.\"\"\"\n        return self._port\n\n    port = property(getPort, setPort, doc=\"Port setting\")\n\n\n    def setBaudrate(self, baudrate):\n        \"\"\"Change baud rate. It raises a ValueError if the port is open and the\n        baud rate is not possible. If the port is closed, then the value is\n        accepted and the exception is raised when the port is opened.\"\"\"\n        try:\n            self._baudrate = int(baudrate)\n        except TypeError:\n            raise ValueError(\"Not a valid baudrate: %r\" % (baudrate,))\n        else:\n            if self._isOpen:  self._reconfigurePort()\n\n    def getBaudrate(self):\n        \"\"\"Get the current baud rate setting.\"\"\"\n        return self._baudrate\n\n    baudrate = property(getBaudrate, setBaudrate, doc=\"Baud rate setting\")\n\n\n    def setByteSize(self, bytesize):\n        \"\"\"Change byte size.\"\"\"\n        if bytesize not in self.BYTESIZES: raise ValueError(\"Not a valid byte size: %r\" % (bytesize,))\n        self._bytesize = bytesize\n        if self._isOpen: self._reconfigurePort()\n\n    def getByteSize(self):\n        \"\"\"Get the current byte size setting.\"\"\"\n        return self._bytesize\n\n    bytesize = property(getByteSize, setByteSize, doc=\"Byte size setting\")\n\n\n    def setParity(self, parity):\n        \"\"\"Change parity setting.\"\"\"\n        if parity not in self.PARITIES: raise ValueError(\"Not a valid parity: %r\" % (parity,))\n        self._parity = parity\n        if self._isOpen: self._reconfigurePort()\n\n    def getParity(self):\n        \"\"\"Get the current parity setting.\"\"\"\n        return self._parity\n\n    parity = property(getParity, setParity, doc=\"Parity setting\")\n\n\n    def setStopbits(self, stopbits):\n        \"\"\"Change stop bits size.\"\"\"\n        if stopbits not in self.STOPBITS: raise ValueError(\"Not a valid stop bit size: %r\" % (stopbits,))\n        self._stopbits = stopbits\n        if self._isOpen: self._reconfigurePort()\n\n    def getStopbits(self):\n        \"\"\"Get the current stop bits setting.\"\"\"\n        return self._stopbits\n\n    stopbits = property(getStopbits, setStopbits, doc=\"Stop bits setting\")\n\n\n    def setTimeout(self, timeout):\n        \"\"\"Change timeout setting.\"\"\"\n        if timeout is not None:\n            try:\n                timeout + 1     # test if it's a number, will throw a TypeError if not...\n            except TypeError:\n                raise ValueError(\"Not a valid timeout: %r\" % (timeout,))\n            if timeout < 0: raise ValueError(\"Not a valid timeout: %r\" % (timeout,))\n        self._timeout = timeout\n        if self._isOpen: self._reconfigurePort()\n\n    def getTimeout(self):\n        \"\"\"Get the current timeout setting.\"\"\"\n        return self._timeout\n\n    timeout = property(getTimeout, setTimeout, doc=\"Timeout setting for read()\")\n\n\n    def setWriteTimeout(self, timeout):\n        \"\"\"Change timeout setting.\"\"\"\n        if timeout is not None:\n            if timeout < 0: raise ValueError(\"Not a valid timeout: %r\" % (timeout,))\n            try:\n                timeout + 1     #test if it's a number, will throw a TypeError if not...\n            except TypeError:\n                raise ValueError(\"Not a valid timeout: %r\" % timeout)\n\n        self._writeTimeout = timeout\n        if self._isOpen: self._reconfigurePort()\n\n    def getWriteTimeout(self):\n        \"\"\"Get the current timeout setting.\"\"\"\n        return self._writeTimeout\n\n    writeTimeout = property(getWriteTimeout, setWriteTimeout, doc=\"Timeout setting for write()\")\n\n\n    def setXonXoff(self, xonxoff):\n        \"\"\"Change XON/XOFF setting.\"\"\"\n        self._xonxoff = xonxoff\n        if self._isOpen: self._reconfigurePort()\n\n    def getXonXoff(self):\n        \"\"\"Get the current XON/XOFF setting.\"\"\"\n        return self._xonxoff\n\n    xonxoff = property(getXonXoff, setXonXoff, doc=\"XON/XOFF setting\")\n\n    def setRtsCts(self, rtscts):\n        \"\"\"Change RTS/CTS flow control setting.\"\"\"\n        self._rtscts = rtscts\n        if self._isOpen: self._reconfigurePort()\n\n    def getRtsCts(self):\n        \"\"\"Get the current RTS/CTS flow control setting.\"\"\"\n        return self._rtscts\n\n    rtscts = property(getRtsCts, setRtsCts, doc=\"RTS/CTS flow control setting\")\n\n    def setDsrDtr(self, dsrdtr=None):\n        \"\"\"Change DsrDtr flow control setting.\"\"\"\n        if dsrdtr is None:\n            # if not set, keep backwards compatibility and follow rtscts setting\n            self._dsrdtr = self._rtscts\n        else:\n            # if defined independently, follow its value\n            self._dsrdtr = dsrdtr\n        if self._isOpen: self._reconfigurePort()\n\n    def getDsrDtr(self):\n        \"\"\"Get the current DSR/DTR flow control setting.\"\"\"\n        return self._dsrdtr\n\n    dsrdtr = property(getDsrDtr, setDsrDtr, \"DSR/DTR flow control setting\")\n\n    def setInterCharTimeout(self, interCharTimeout):\n        \"\"\"Change inter-character timeout setting.\"\"\"\n        if interCharTimeout is not None:\n            if interCharTimeout < 0: raise ValueError(\"Not a valid timeout: %r\" % interCharTimeout)\n            try:\n                interCharTimeout + 1     # test if it's a number, will throw a TypeError if not...\n            except TypeError:\n                raise ValueError(\"Not a valid timeout: %r\" % interCharTimeout)\n\n        self._interCharTimeout = interCharTimeout\n        if self._isOpen: self._reconfigurePort()\n\n    def getInterCharTimeout(self):\n        \"\"\"Get the current inter-character timeout setting.\"\"\"\n        return self._interCharTimeout\n\n    interCharTimeout = property(getInterCharTimeout, setInterCharTimeout, doc=\"Inter-character timeout setting for read()\")\n\n    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n\n    _SETTINGS = ('baudrate', 'bytesize', 'parity', 'stopbits', 'xonxoff',\n            'dsrdtr', 'rtscts', 'timeout', 'writeTimeout', 'interCharTimeout')\n\n    def getSettingsDict(self):\n        \"\"\"Get current port settings as a dictionary. For use with\n        applySettingsDict\"\"\"\n        return dict([(key, getattr(self, '_'+key)) for key in self._SETTINGS])\n\n    def applySettingsDict(self, d):\n        \"\"\"apply stored settings from a dictionary returned from\n        getSettingsDict. it's allowed to delete keys from the dictionary. these\n        values will simply left unchanged.\"\"\"\n        for key in self._SETTINGS:\n            if d[key] != getattr(self, '_'+key):   # check against internal \"_\" value\n                setattr(self, key, d[key])          # set non \"_\" value to use properties write function\n\n    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n\n    def __repr__(self):\n        \"\"\"String representation of the current port settings and its state.\"\"\"\n        return \"%s<id=0x%x, open=%s>(port=%r, baudrate=%r, bytesize=%r, parity=%r, stopbits=%r, timeout=%r, xonxoff=%r, rtscts=%r, dsrdtr=%r)\" % (\n            self.__class__.__name__,\n            id(self),\n            self._isOpen,\n            self.portstr,\n            self.baudrate,\n            self.bytesize,\n            self.parity,\n            self.stopbits,\n            self.timeout,\n            self.xonxoff,\n            self.rtscts,\n            self.dsrdtr,\n        )\n\n\n    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n    # compatibility with io library\n\n    def readable(self): return True\n    def writable(self): return True\n    def seekable(self): return False\n    def readinto(self, b):\n        data = self.read(len(b))\n        n = len(data)\n        try:\n            b[:n] = data\n        except TypeError, err:\n            import array\n            if not isinstance(b, array.array):\n                raise err\n            b[:n] = array.array('b', data)\n        return n\n\n\nif __name__ == '__main__':\n    import sys\n    s = SerialBase()\n    sys.stdout.write('port name:  %s\\n' % s.portstr)\n    sys.stdout.write('baud rates: %s\\n' % s.getSupportedBaudrates())\n    sys.stdout.write('byte sizes: %s\\n' % s.getSupportedByteSizes())\n    sys.stdout.write('parities:   %s\\n' % s.getSupportedParities())\n    sys.stdout.write('stop bits:  %s\\n' % s.getSupportedStopbits())\n    sys.stdout.write('%s\\n' % s)\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/serialwin32.py",
    "content": "#! python\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# serial driver for win32\n# see __init__.py\n#\n# (C) 2001-2011 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n#\n# Initial patch to use ctypes by Giovanni Bajo <rasky@develer.com>\n\nimport ctypes\nfrom serial import win32\n\nfrom serial.serialutil import *\n\n\ndef device(portnum):\n    \"\"\"Turn a port number into a device name\"\"\"\n    return 'COM%d' % (portnum+1) # numbers are transformed to a string\n\n\nclass Win32Serial(SerialBase):\n    \"\"\"Serial port implementation for Win32 based on ctypes.\"\"\"\n\n    BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,\n                 9600, 19200, 38400, 57600, 115200)\n\n    def __init__(self, *args, **kwargs):\n        self.hComPort = None\n        self._rtsToggle = False\n        SerialBase.__init__(self, *args, **kwargs)\n\n    def open(self):\n        \"\"\"Open port with current settings. This may throw a SerialException\n           if the port cannot be opened.\"\"\"\n        if self._port is None:\n            raise SerialException(\"Port must be configured before it can be used.\")\n        if self._isOpen:\n            raise SerialException(\"Port is already open.\")\n        # the \"\\\\.\\COMx\" format is required for devices other than COM1-COM8\n        # not all versions of windows seem to support this properly\n        # so that the first few ports are used with the DOS device name\n        port = self.portstr\n        try:\n            if port.upper().startswith('COM') and int(port[3:]) > 8:\n                port = '\\\\\\\\.\\\\' + port\n        except ValueError:\n            # for like COMnotanumber\n            pass\n        self.hComPort = win32.CreateFile(port,\n               win32.GENERIC_READ | win32.GENERIC_WRITE,\n               0, # exclusive access\n               None, # no security\n               win32.OPEN_EXISTING,\n               win32.FILE_ATTRIBUTE_NORMAL | win32.FILE_FLAG_OVERLAPPED,\n               0)\n        if self.hComPort == win32.INVALID_HANDLE_VALUE:\n            self.hComPort = None    # 'cause __del__ is called anyway\n            raise SerialException(\"could not open port %s: %s\" % (self.portstr, ctypes.WinError()))\n\n        # Setup a 4k buffer\n        win32.SetupComm(self.hComPort, 4096, 4096)\n\n        # Save original timeout values:\n        self._orgTimeouts = win32.COMMTIMEOUTS()\n        win32.GetCommTimeouts(self.hComPort, ctypes.byref(self._orgTimeouts))\n\n        self._rtsState = win32.RTS_CONTROL_ENABLE\n        self._dtrState = win32.DTR_CONTROL_ENABLE\n\n        self._reconfigurePort()\n\n        # Clear buffers:\n        # Remove anything that was there\n        win32.PurgeComm(self.hComPort,\n                            win32.PURGE_TXCLEAR | win32.PURGE_TXABORT |\n                            win32.PURGE_RXCLEAR | win32.PURGE_RXABORT)\n\n        self._overlappedRead = win32.OVERLAPPED()\n        self._overlappedRead.hEvent = win32.CreateEvent(None, 1, 0, None)\n        self._overlappedWrite = win32.OVERLAPPED()\n        #~ self._overlappedWrite.hEvent = win32.CreateEvent(None, 1, 0, None)\n        self._overlappedWrite.hEvent = win32.CreateEvent(None, 0, 0, None)\n        self._isOpen = True\n\n    def _reconfigurePort(self):\n        \"\"\"Set communication parameters on opened port.\"\"\"\n        if not self.hComPort:\n            raise SerialException(\"Can only operate on a valid port handle\")\n\n        # Set Windows timeout values\n        # timeouts is a tuple with the following items:\n        # (ReadIntervalTimeout,ReadTotalTimeoutMultiplier,\n        #  ReadTotalTimeoutConstant,WriteTotalTimeoutMultiplier,\n        #  WriteTotalTimeoutConstant)\n        if self._timeout is None:\n            timeouts = (0, 0, 0, 0, 0)\n        elif self._timeout == 0:\n            timeouts = (win32.MAXDWORD, 0, 0, 0, 0)\n        else:\n            timeouts = (0, 0, int(self._timeout*1000), 0, 0)\n        if self._timeout != 0 and self._interCharTimeout is not None:\n            timeouts = (int(self._interCharTimeout * 1000),) + timeouts[1:]\n\n        if self._writeTimeout is None:\n            pass\n        elif self._writeTimeout == 0:\n            timeouts = timeouts[:-2] + (0, win32.MAXDWORD)\n        else:\n            timeouts = timeouts[:-2] + (0, int(self._writeTimeout*1000))\n        win32.SetCommTimeouts(self.hComPort, ctypes.byref(win32.COMMTIMEOUTS(*timeouts)))\n\n        win32.SetCommMask(self.hComPort, win32.EV_ERR)\n\n        # Setup the connection info.\n        # Get state and modify it:\n        comDCB = win32.DCB()\n        win32.GetCommState(self.hComPort, ctypes.byref(comDCB))\n        comDCB.BaudRate = self._baudrate\n\n        if self._bytesize == FIVEBITS:\n            comDCB.ByteSize     = 5\n        elif self._bytesize == SIXBITS:\n            comDCB.ByteSize     = 6\n        elif self._bytesize == SEVENBITS:\n            comDCB.ByteSize     = 7\n        elif self._bytesize == EIGHTBITS:\n            comDCB.ByteSize     = 8\n        else:\n            raise ValueError(\"Unsupported number of data bits: %r\" % self._bytesize)\n\n        if self._parity == PARITY_NONE:\n            comDCB.Parity       = win32.NOPARITY\n            comDCB.fParity      = 0 # Disable Parity Check\n        elif self._parity == PARITY_EVEN:\n            comDCB.Parity       = win32.EVENPARITY\n            comDCB.fParity      = 1 # Enable Parity Check\n        elif self._parity == PARITY_ODD:\n            comDCB.Parity       = win32.ODDPARITY\n            comDCB.fParity      = 1 # Enable Parity Check\n        elif self._parity == PARITY_MARK:\n            comDCB.Parity       = win32.MARKPARITY\n            comDCB.fParity      = 1 # Enable Parity Check\n        elif self._parity == PARITY_SPACE:\n            comDCB.Parity       = win32.SPACEPARITY\n            comDCB.fParity      = 1 # Enable Parity Check\n        else:\n            raise ValueError(\"Unsupported parity mode: %r\" % self._parity)\n\n        if self._stopbits == STOPBITS_ONE:\n            comDCB.StopBits     = win32.ONESTOPBIT\n        elif self._stopbits == STOPBITS_ONE_POINT_FIVE:\n            comDCB.StopBits     = win32.ONE5STOPBITS\n        elif self._stopbits == STOPBITS_TWO:\n            comDCB.StopBits     = win32.TWOSTOPBITS\n        else:\n            raise ValueError(\"Unsupported number of stop bits: %r\" % self._stopbits)\n\n        comDCB.fBinary          = 1 # Enable Binary Transmission\n        # Char. w/ Parity-Err are replaced with 0xff (if fErrorChar is set to TRUE)\n        if self._rtscts:\n            comDCB.fRtsControl  = win32.RTS_CONTROL_HANDSHAKE\n        elif self._rtsToggle:\n            comDCB.fRtsControl  = win32.RTS_CONTROL_TOGGLE\n        else:\n            comDCB.fRtsControl  = self._rtsState\n        if self._dsrdtr:\n            comDCB.fDtrControl  = win32.DTR_CONTROL_HANDSHAKE\n        else:\n            comDCB.fDtrControl  = self._dtrState\n\n        if self._rtsToggle:\n            comDCB.fOutxCtsFlow     = 0\n        else:\n            comDCB.fOutxCtsFlow     = self._rtscts\n        comDCB.fOutxDsrFlow     = self._dsrdtr\n        comDCB.fOutX            = self._xonxoff\n        comDCB.fInX             = self._xonxoff\n        comDCB.fNull            = 0\n        comDCB.fErrorChar       = 0\n        comDCB.fAbortOnError    = 0\n        comDCB.XonChar          = XON\n        comDCB.XoffChar         = XOFF\n\n        if not win32.SetCommState(self.hComPort, ctypes.byref(comDCB)):\n            raise ValueError(\"Cannot configure port, some setting was wrong. Original message: %s\" % ctypes.WinError())\n\n    #~ def __del__(self):\n        #~ self.close()\n\n    def close(self):\n        \"\"\"Close port\"\"\"\n        if self._isOpen:\n            if self.hComPort:\n                # Restore original timeout values:\n                win32.SetCommTimeouts(self.hComPort, self._orgTimeouts)\n                # Close COM-Port:\n                win32.CloseHandle(self.hComPort)\n                win32.CloseHandle(self._overlappedRead.hEvent)\n                win32.CloseHandle(self._overlappedWrite.hEvent)\n                self.hComPort = None\n            self._isOpen = False\n\n    def makeDeviceName(self, port):\n        return device(port)\n\n    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n\n    def inWaiting(self):\n        \"\"\"Return the number of characters currently in the input buffer.\"\"\"\n        flags = win32.DWORD()\n        comstat = win32.COMSTAT()\n        if not win32.ClearCommError(self.hComPort, ctypes.byref(flags), ctypes.byref(comstat)):\n            raise SerialException('call to ClearCommError failed')\n        return comstat.cbInQue\n\n    def read(self, size=1):\n        \"\"\"Read size bytes from the serial port. If a timeout is set it may\n           return less characters as requested. With no timeout it will block\n           until the requested number of bytes is read.\"\"\"\n        if not self.hComPort: raise portNotOpenError\n        if size > 0:\n            win32.ResetEvent(self._overlappedRead.hEvent)\n            flags = win32.DWORD()\n            comstat = win32.COMSTAT()\n            if not win32.ClearCommError(self.hComPort, ctypes.byref(flags), ctypes.byref(comstat)):\n                raise SerialException('call to ClearCommError failed')\n            if self.timeout == 0:\n                n = min(comstat.cbInQue, size)\n                if n > 0:\n                    buf = ctypes.create_string_buffer(n)\n                    rc = win32.DWORD()\n                    err = win32.ReadFile(self.hComPort, buf, n, ctypes.byref(rc), ctypes.byref(self._overlappedRead))\n                    if not err and win32.GetLastError() != win32.ERROR_IO_PENDING:\n                        raise SerialException(\"ReadFile failed (%s)\" % ctypes.WinError())\n                    err = win32.WaitForSingleObject(self._overlappedRead.hEvent, win32.INFINITE)\n                    read = buf.raw[:rc.value]\n                else:\n                    read = bytes()\n            else:\n                buf = ctypes.create_string_buffer(size)\n                rc = win32.DWORD()\n                err = win32.ReadFile(self.hComPort, buf, size, ctypes.byref(rc), ctypes.byref(self._overlappedRead))\n                if not err and win32.GetLastError() != win32.ERROR_IO_PENDING:\n                    raise SerialException(\"ReadFile failed (%s)\" % ctypes.WinError())\n                err = win32.GetOverlappedResult(self.hComPort, ctypes.byref(self._overlappedRead), ctypes.byref(rc), True)\n                read = buf.raw[:rc.value]\n        else:\n            read = bytes()\n        return bytes(read)\n\n    def write(self, data):\n        \"\"\"Output the given string over the serial port.\"\"\"\n        if not self.hComPort: raise portNotOpenError\n        #~ if not isinstance(data, (bytes, bytearray)):\n            #~ raise TypeError('expected %s or bytearray, got %s' % (bytes, type(data)))\n        # convert data (needed in case of memoryview instance: Py 3.1 io lib), ctypes doesn't like memoryview\n        data = bytes(data)\n        if data:\n            #~ win32event.ResetEvent(self._overlappedWrite.hEvent)\n            n = win32.DWORD()\n            err = win32.WriteFile(self.hComPort, data, len(data), ctypes.byref(n), self._overlappedWrite)\n            if not err and win32.GetLastError() != win32.ERROR_IO_PENDING:\n                raise SerialException(\"WriteFile failed (%s)\" % ctypes.WinError())\n            if self._writeTimeout != 0: # if blocking (None) or w/ write timeout (>0)\n                # Wait for the write to complete.\n                #~ win32.WaitForSingleObject(self._overlappedWrite.hEvent, win32.INFINITE)\n                err = win32.GetOverlappedResult(self.hComPort, self._overlappedWrite, ctypes.byref(n), True)\n                if n.value != len(data):\n                    raise writeTimeoutError\n            return n.value\n        else:\n            return 0\n\n\n    def flushInput(self):\n        \"\"\"Clear input buffer, discarding all that is in the buffer.\"\"\"\n        if not self.hComPort: raise portNotOpenError\n        win32.PurgeComm(self.hComPort, win32.PURGE_RXCLEAR | win32.PURGE_RXABORT)\n\n    def flushOutput(self):\n        \"\"\"Clear output buffer, aborting the current output and\n        discarding all that is in the buffer.\"\"\"\n        if not self.hComPort: raise portNotOpenError\n        win32.PurgeComm(self.hComPort, win32.PURGE_TXCLEAR | win32.PURGE_TXABORT)\n\n    def sendBreak(self, duration=0.25):\n        \"\"\"Send break condition. Timed, returns to idle state after given duration.\"\"\"\n        if not self.hComPort: raise portNotOpenError\n        import time\n        win32.SetCommBreak(self.hComPort)\n        time.sleep(duration)\n        win32.ClearCommBreak(self.hComPort)\n\n    def setBreak(self, level=1):\n        \"\"\"Set break: Controls TXD. When active, to transmitting is possible.\"\"\"\n        if not self.hComPort: raise portNotOpenError\n        if level:\n            win32.SetCommBreak(self.hComPort)\n        else:\n            win32.ClearCommBreak(self.hComPort)\n\n    def setRTS(self, level=1):\n        \"\"\"Set terminal status line: Request To Send\"\"\"\n        if not self.hComPort: raise portNotOpenError\n        if level:\n            self._rtsState = win32.RTS_CONTROL_ENABLE\n            win32.EscapeCommFunction(self.hComPort, win32.SETRTS)\n        else:\n            self._rtsState = win32.RTS_CONTROL_DISABLE\n            win32.EscapeCommFunction(self.hComPort, win32.CLRRTS)\n\n    def setDTR(self, level=1):\n        \"\"\"Set terminal status line: Data Terminal Ready\"\"\"\n        if not self.hComPort: raise portNotOpenError\n        if level:\n            self._dtrState = win32.DTR_CONTROL_ENABLE\n            win32.EscapeCommFunction(self.hComPort, win32.SETDTR)\n        else:\n            self._dtrState = win32.DTR_CONTROL_DISABLE\n            win32.EscapeCommFunction(self.hComPort, win32.CLRDTR)\n\n    def _GetCommModemStatus(self):\n        stat = win32.DWORD()\n        win32.GetCommModemStatus(self.hComPort, ctypes.byref(stat))\n        return stat.value\n\n    def getCTS(self):\n        \"\"\"Read terminal status line: Clear To Send\"\"\"\n        if not self.hComPort: raise portNotOpenError\n        return win32.MS_CTS_ON & self._GetCommModemStatus() != 0\n\n    def getDSR(self):\n        \"\"\"Read terminal status line: Data Set Ready\"\"\"\n        if not self.hComPort: raise portNotOpenError\n        return win32.MS_DSR_ON & self._GetCommModemStatus() != 0\n\n    def getRI(self):\n        \"\"\"Read terminal status line: Ring Indicator\"\"\"\n        if not self.hComPort: raise portNotOpenError\n        return win32.MS_RING_ON & self._GetCommModemStatus() != 0\n\n    def getCD(self):\n        \"\"\"Read terminal status line: Carrier Detect\"\"\"\n        if not self.hComPort: raise portNotOpenError\n        return win32.MS_RLSD_ON & self._GetCommModemStatus() != 0\n\n    # - - platform specific - - - -\n\n    def setXON(self, level=True):\n        \"\"\"Platform specific - set flow state.\"\"\"\n        if not self.hComPort: raise portNotOpenError\n        if level:\n            win32.EscapeCommFunction(self.hComPort, win32.SETXON)\n        else:\n            win32.EscapeCommFunction(self.hComPort, win32.SETXOFF)\n\n    def outWaiting(self):\n        \"\"\"return how many characters the in the outgoing buffer\"\"\"\n        flags = win32.DWORD()\n        comstat = win32.COMSTAT()\n        if not win32.ClearCommError(self.hComPort, ctypes.byref(flags), ctypes.byref(comstat)):\n            raise SerialException('call to ClearCommError failed')\n        return comstat.cbOutQue\n\n    # functions useful for RS-485 adapters\n    def setRtsToggle(self, rtsToggle):\n        \"\"\"Change RTS toggle control setting.\"\"\"\n        self._rtsToggle = rtsToggle\n        if self._isOpen: self._reconfigurePort()\n\n    def getRtsToggle(self):\n        \"\"\"Get the current RTS toggle control setting.\"\"\"\n        return self._rtsToggle\n\n    rtsToggle = property(getRtsToggle, setRtsToggle, doc=\"RTS toggle control setting\")\n\n\n# assemble Serial class with the platform specific implementation and the base\n# for file-like behavior. for Python 2.6 and newer, that provide the new I/O\n# library, derive from io.RawIOBase\ntry:\n    import io\nexcept ImportError:\n    # classic version with our own file-like emulation\n    class Serial(Win32Serial, FileLike):\n        pass\nelse:\n    # io library present\n    class Serial(Win32Serial, io.RawIOBase):\n        pass\n\n\n# Nur Testfunktion!!\nif __name__ == '__main__':\n    s = Serial(0)\n    sys.stdout.write(\"%s\\n\" % s)\n\n    s = Serial()\n    sys.stdout.write(\"%s\\n\" % s)\n\n    s.baudrate = 19200\n    s.databits = 7\n    s.close()\n    s.port = 0\n    s.open()\n    sys.stdout.write(\"%s\\n\" % s)\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/sermsdos.py",
    "content": "# sermsdos.py\n#\n# History:\n#\n#   3rd September 2002                      Dave Haynes\n#   1. First defined\n#\n# Although this code should run under the latest versions of\n# Python, on DOS-based platforms such as Windows 95 and 98,\n# it has been specifically written to be compatible with\n# PyDOS, available at:\n# http://www.python.org/ftp/python/wpy/dos.html\n#\n# PyDOS is a stripped-down version of Python 1.5.2 for\n# DOS machines. Therefore, in making changes to this file,\n# please respect Python 1.5.2 syntax. In addition, please\n# limit the width of this file to 60 characters.\n#\n# Note also that the modules in PyDOS contain fewer members\n# than other versions, so we are restricted to using the\n# following:\n#\n# In module os:\n# -------------\n# environ, chdir, getcwd, getpid, umask, fdopen, close,\n# dup, dup2, fstat, lseek, open, read, write, O_RDONLY,\n# O_WRONLY, O_RDWR, O_APPEND, O_CREAT, O_EXCL, O_TRUNC,\n# access, F_OK, R_OK, W_OK, X_OK, chmod, listdir, mkdir,\n# remove, rename, renames, rmdir, stat, unlink, utime,\n# execl, execle, execlp, execlpe, execvp, execvpe, _exit,\n# system.\n#\n# In module os.path:\n# ------------------\n# curdir, pardir, sep, altsep, pathsep, defpath, linesep.\n#\n\nimport os\nimport sys\nimport string\nimport serial.serialutil\n\nBAUD_RATES = {\n                110: \"11\",\n                150: \"15\",\n                300: \"30\",\n                600: \"60\",\n                1200: \"12\",\n                2400: \"24\",\n                4800: \"48\",\n                9600: \"96\",\n                19200: \"19\"}\n\n(PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK,\nPARITY_SPACE) = (0, 1, 2, 3, 4)\n(STOPBITS_ONE, STOPBITS_ONEANDAHALF,\nSTOPBITS_TWO) = (1, 1.5, 2)\nFIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5, 6, 7, 8)\n(RETURN_ERROR, RETURN_BUSY, RETURN_RETRY, RETURN_READY,\nRETURN_NONE) = ('E', 'B', 'P', 'R', 'N')\nportNotOpenError = ValueError('port not open')\n\ndef device(portnum):\n    return 'COM%d' % (portnum+1)\n\nclass Serial(serialutil.FileLike):\n    \"\"\"\n       port: number of device; numbering starts at\n            zero. if everything fails, the user can\n            specify a device string, note that this\n            isn't portable any more\n       baudrate: baud rate\n       bytesize: number of databits\n       parity: enable parity checking\n       stopbits: number of stopbits\n       timeout: set a timeout (None for waiting forever)\n       xonxoff: enable software flow control\n       rtscts: enable RTS/CTS flow control\n       retry: DOS retry mode\n    \"\"\"\n    def __init__(self,\n                 port,\n                 baudrate = 9600,\n                 bytesize = EIGHTBITS,\n                 parity = PARITY_NONE,\n                 stopbits = STOPBITS_ONE,\n                 timeout = None,\n                 xonxoff = 0,\n                 rtscts = 0,\n                 retry = RETURN_RETRY\n                 ):\n\n        if type(port) == type(''):\n        # strings are taken directly\n            self.portstr = port\n        else:\n        # numbers are transformed to a string\n            self.portstr = device(port+1)\n\n        self.baud = BAUD_RATES[baudrate]\n        self.bytesize = str(bytesize)\n\n        if parity == PARITY_NONE:\n            self.parity = 'N'\n        elif parity == PARITY_EVEN:\n            self.parity = 'E'\n        elif parity == PARITY_ODD:\n            self.parity = 'O'\n        elif parity == PARITY_MARK:\n            self.parity = 'M'\n        elif parity == PARITY_SPACE:\n            self.parity = 'S'\n\n        self.stop = str(stopbits)\n        self.retry = retry\n        self.filename = \"sermsdos.tmp\"\n\n        self._config(self.portstr, self.baud, self.parity,\n        self.bytesize, self.stop, self.retry, self.filename)\n\n    def __del__(self):\n        self.close()\n\n    def close(self):\n        pass\n\n    def _config(self, port, baud, parity, data, stop, retry,\n        filename):\n        comString = string.join((\"MODE \", port, \":\"\n        , \" BAUD= \", baud, \" PARITY= \", parity\n        , \" DATA= \", data, \" STOP= \", stop, \" RETRY= \",\n        retry, \" > \", filename ), '')\n        os.system(comString)\n\n    def setBaudrate(self, baudrate):\n        self._config(self.portstr, BAUD_RATES[baudrate],\n        self.parity, self.bytesize, self.stop, self.retry,\n        self.filename)\n\n    def inWaiting(self):\n        \"\"\"returns the number of bytes waiting to be read\"\"\"\n        raise NotImplementedError\n\n    def read(self, num = 1):\n        \"\"\"Read num bytes from serial port\"\"\"\n        handle = os.open(self.portstr,\n        os.O_RDONLY | os.O_BINARY)\n        rv = os.read(handle, num)\n        os.close(handle)\n        return rv\n\n    def write(self, s):\n        \"\"\"Write string to serial port\"\"\"\n        handle = os.open(self.portstr,\n        os.O_WRONLY | os.O_BINARY)\n        rv = os.write(handle, s)\n        os.close(handle)\n        return rv\n\n    def flushInput(self):\n        raise NotImplementedError\n\n    def flushOutput(self):\n        raise NotImplementedError\n\n    def sendBreak(self):\n        raise NotImplementedError\n\n    def setRTS(self,level=1):\n        \"\"\"Set terminal status line\"\"\"\n        raise NotImplementedError\n\n    def setDTR(self,level=1):\n        \"\"\"Set terminal status line\"\"\"\n        raise NotImplementedError\n\n    def getCTS(self):\n        \"\"\"Eead terminal status line\"\"\"\n        raise NotImplementedError\n\n    def getDSR(self):\n        \"\"\"Eead terminal status line\"\"\"\n        raise NotImplementedError\n\n    def getRI(self):\n        \"\"\"Eead terminal status line\"\"\"\n        raise NotImplementedError\n\n    def getCD(self):\n        \"\"\"Eead terminal status line\"\"\"\n        raise NotImplementedError\n\n    def __repr__(self):\n        return string.join(( \"<Serial>: \", self.portstr\n        , self.baud, self.parity, self.bytesize, self.stop,\n        self.retry , self.filename), ' ')\n\nif __name__ == '__main__':\n    s = Serial(0)\n    sys.stdio.write('%s %s\\n' % (__name__, s))\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/tools/__init__.py",
    "content": ""
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/tools/list_ports.py",
    "content": "#!/usr/bin/env python\n\n# portable serial port access with python\n# this is a wrapper module for different platform implementations of the\n# port enumeration feature\n#\n# (C) 2011 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n\n\"\"\"\\\nThis module will provide a function called comports that returns an\niterable (generator or list) that will enumerate available com ports. Note that\non some systems non-existent ports may be listed.\n\nAdditionally a grep function is supplied that can be used to search for ports\nbased on their descriptions or hardware ID.\n\"\"\"\n\nimport sys, os, re\n\n# chose an implementation, depending on os\n#~ if sys.platform == 'cli':\n#~ else:\nimport os\n# chose an implementation, depending on os\nif os.name == 'nt': #sys.platform == 'win32':\n    from serial.tools.list_ports_windows import *\nelif os.name == 'posix':\n    from serial.tools.list_ports_posix import *\n#~ elif os.name == 'java':\nelse:\n    raise ImportError(\"Sorry: no implementation for your platform ('%s') available\" % (os.name,))\n\n\ndef grep(regexp):\n    \"\"\"\\\n    Search for ports using a regular expression. Port name, description and\n    hardware ID are searched. The function returns an iterable that returns the\n    same tuples as comport() would do.\n    \"\"\"\n    for port, desc, hwid in comports():\n        if re.search(regexp, port, re.I) or re.search(regexp, desc) or re.search(regexp, hwid):\n            yield port, desc, hwid\n\n\ndef main():\n    import optparse\n\n    parser = optparse.OptionParser(\n        usage = \"%prog [options] [<regexp>]\",\n        description = \"Miniterm - A simple terminal program for the serial port.\"\n    )\n    \n    parser.add_option(\"--debug\",\n            help=\"print debug messages and tracebacks (development mode)\",\n            dest=\"debug\",\n            default=False,\n            action='store_true')\n\n    parser.add_option(\"-v\", \"--verbose\",\n            help=\"show more messages (can be given multiple times)\",\n            dest=\"verbose\",\n            default=1,\n            action='count')\n\n    parser.add_option(\"-q\", \"--quiet\",\n            help=\"suppress all messages\",\n            dest=\"verbose\",\n            action='store_const',\n            const=0)\n\n    (options, args) = parser.parse_args()\n\n\n    hits = 0\n    # get iteraror w/ or w/o filter\n    if args:\n        if len(args) > 1:\n            parser.error('more than one regexp not supported')\n        print \"Filtered list with regexp: %r\" % (args[0],)\n        iterator = sorted(grep(args[0]))\n    else:\n        iterator = sorted(comports())\n    # list them\n    for port, desc, hwid in iterator:\n        print \"%-20s\" % (port,)\n        if options.verbose > 1:\n            print \"    desc: %s\" % (desc,)\n            print \"    hwid: %s\" % (hwid,)\n        hits += 1\n    if options.verbose:\n        if hits:\n            print \"%d ports found\" % (hits,)\n        else:\n            print \"no ports found\"\n\n# test\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/tools/list_ports_posix.py",
    "content": "import glob\nimport sys\nimport os\nimport re\n\ntry:\n    import subprocess\nexcept ImportError:\n    def popen(argv):\n        try:\n            si, so =  os.popen4(' '.join(argv))\n            return so.read().strip()\n        except:\n            raise IOError('lsusb failed')\nelse:\n    def popen(argv):\n        try:\n            return subprocess.check_output(argv, stderr=subprocess.STDOUT).strip()\n        except:\n            raise IOError('lsusb failed')\n\n\n# The comports function is expected to return an iterable that yields tuples of\n# 3 strings: port name, human readable description and a hardware ID.\n#\n# as currently no method is known to get the second two strings easily, they\n# are currently just identical to the port name.\n\n# try to detect the OS so that a device can be selected...\nplat = sys.platform.lower()\n\ndef read_line(filename):\n    \"\"\"help function to read a single line from a file. returns none\"\"\"\n    try:\n        f = open(filename)\n        line = f.readline().strip()\n        f.close()\n        return line\n    except IOError:\n        return None\n\ndef re_group(regexp, text):\n    \"\"\"search for regexp in text, return 1st group on match\"\"\"\n    m = re.search(regexp, text)\n    if m: return m.group(1)\n\n\nif   plat[:5] == 'linux':    # Linux (confirmed)\n    # try to extract descriptions from sysfs. this was done by experimenting,\n    # no guarantee that it works for all devices or in the future...\n\n    def usb_sysfs_hw_string(sysfs_path):\n        \"\"\"given a path to a usb device in sysfs, return a string describing it\"\"\"\n        bus, dev = os.path.basename(os.path.realpath(sysfs_path)).split('-')\n        snr = read_line(sysfs_path+'/serial')\n        if snr:\n            snr_txt = ' SNR=%s' % (snr,)\n        else:\n            snr_txt = ''\n        return 'USB VID:PID=%s:%s%s' % (\n                read_line(sysfs_path+'/idVendor'),\n                read_line(sysfs_path+'/idProduct'),\n                snr_txt\n                )\n\n    def usb_lsusb_string(sysfs_path):\n        bus, dev = os.path.basename(os.path.realpath(sysfs_path)).split('-')\n        try:\n            desc = popen(['lsusb', '-v', '-s', '%s:%s' % (bus, dev)])\n            # descriptions from device\n            iManufacturer = re_group('iManufacturer\\s+\\w+ (.+)', desc)\n            iProduct = re_group('iProduct\\s+\\w+ (.+)', desc)\n            iSerial = re_group('iSerial\\s+\\w+ (.+)', desc) or ''\n            # descriptions from kernel\n            idVendor = re_group('idVendor\\s+0x\\w+ (.+)', desc)\n            idProduct = re_group('idProduct\\s+0x\\w+ (.+)', desc)\n            # create descriptions. prefer text from device, fall back to the others\n            return '%s %s %s' % (iManufacturer or idVendor, iProduct or idProduct, iSerial)\n        except IOError:\n            return base\n\n    def describe(device):\n        \"\"\"\\\n        Get a human readable description.\n        For USB-Serial devices try to run lsusb to get a human readable description.\n        For USB-CDC devices read the description from sysfs.\n        \"\"\"\n        base = os.path.basename(device)\n        # USB-Serial devices\n        sys_dev_path = '/sys/class/tty/%s/device/driver/%s' % (base, base)\n        if os.path.exists(sys_dev_path):\n            sys_usb = os.path.dirname(os.path.dirname(os.path.realpath(sys_dev_path)))\n            return usb_lsusb_string(sys_usb)\n        # USB-CDC devices\n        sys_dev_path = '/sys/class/tty/%s/device/interface' % (base,)\n        if os.path.exists(sys_dev_path):\n            return read_line(sys_dev_path)\n        return base\n\n    def hwinfo(device):\n        \"\"\"Try to get a HW identification using sysfs\"\"\"\n        base = os.path.basename(device)\n        if os.path.exists('/sys/class/tty/%s/device' % (base,)):\n            # PCI based devices\n            sys_id_path = '/sys/class/tty/%s/device/id' % (base,)\n            if os.path.exists(sys_id_path):\n                return read_line(sys_id_path)\n            # USB-Serial devices\n            sys_dev_path = '/sys/class/tty/%s/device/driver/%s' % (base, base)\n            if os.path.exists(sys_dev_path):\n                sys_usb = os.path.dirname(os.path.dirname(os.path.realpath(sys_dev_path)))\n                return usb_sysfs_hw_string(sys_usb)\n            # USB-CDC devices\n            if base.startswith('ttyACM'):\n                sys_dev_path = '/sys/class/tty/%s/device' % (base,)\n                if os.path.exists(sys_dev_path):\n                    return usb_sysfs_hw_string(sys_dev_path + '/..')\n        return 'n/a'    # XXX directly remove these from the list?\n\n    def comports():\n        devices = glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*')\n        return [(d, describe(d), hwinfo(d)) for d in devices]\n\nelif plat == 'cygwin':       # cygwin/win32\n    def comports():\n        devices = glob.glob('/dev/com*')\n        return [(d, d, d) for d in devices]\n\nelif plat == 'openbsd3':    # BSD\n    def comports():\n        devices = glob.glob('/dev/ttyp*')\n        return [(d, d, d) for d in devices]\n\nelif plat[:3] == 'bsd' or  \\\n     plat[:7] == 'freebsd' or \\\n     plat[:7] == 'openbsd':  # BSD\n\n    def comports():\n        devices = glob.glob('/dev/cuad*')\n        return [(d, d, d) for d in devices]\n\nelif plat[:6] == 'darwin':   # OS X (confirmed)\n    def comports():\n        \"\"\"scan for available ports. return a list of device names.\"\"\"\n        devices = glob.glob('/dev/tty.*')\n        return [(d, d, d) for d in devices]\n\nelif plat[:6] == 'netbsd':   # NetBSD\n    def comports():\n        \"\"\"scan for available ports. return a list of device names.\"\"\"\n        devices = glob.glob('/dev/dty*')\n        return [(d, d, d) for d in devices]\n\nelif plat[:4] == 'irix':     # IRIX\n    def comports():\n        \"\"\"scan for available ports. return a list of device names.\"\"\"\n        devices = glob.glob('/dev/ttyf*')\n        return [(d, d, d) for d in devices]\n\nelif plat[:2] == 'hp':       # HP-UX (not tested)\n    def comports():\n        \"\"\"scan for available ports. return a list of device names.\"\"\"\n        devices = glob.glob('/dev/tty*p0')\n        return [(d, d, d) for d in devices]\n\nelif plat[:5] == 'sunos':    # Solaris/SunOS\n    def comports():\n        \"\"\"scan for available ports. return a list of device names.\"\"\"\n        devices = glob.glob('/dev/tty*c')\n        return [(d, d, d) for d in devices]\n\nelif plat[:3] == 'aix':      # AIX\n    def comports():\n        \"\"\"scan for available ports. return a list of device names.\"\"\"\n        devices = glob.glob('/dev/tty*')\n        return [(d, d, d) for d in devices]\n\nelse:\n    # platform detection has failed...\n    sys.stderr.write(\"\"\"\\\ndon't know how to enumerate ttys on this system.\n! I you know how the serial ports are named send this information to\n! the author of this module:\n\nsys.platform = %r\nos.name = %r\npySerial version = %s\n\nalso add the naming scheme of the serial ports and with a bit luck you can get\nthis module running...\n\"\"\" % (sys.platform, os.name, serial.VERSION))\n    raise ImportError(\"Sorry: no implementation for your platform ('%s') available\" % (os.name,))\n\n# test\nif __name__ == '__main__':\n    for port, desc, hwid in sorted(comports()):\n        print \"%s: %s [%s]\" % (port, desc, hwid)\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/tools/list_ports_windows.py",
    "content": "import ctypes\nimport re\n\ndef ValidHandle(value, func, arguments):\n    if value == 0:\n        raise ctypes.WinError()\n    return value\n\nimport serial\nfrom serial.win32 import ULONG_PTR, is_64bit\nfrom ctypes.wintypes import HANDLE\nfrom ctypes.wintypes import BOOL\nfrom ctypes.wintypes import HWND\nfrom ctypes.wintypes import DWORD\nfrom ctypes.wintypes import WORD\nfrom ctypes.wintypes import LONG\nfrom ctypes.wintypes import ULONG\nfrom ctypes.wintypes import LPCSTR\nfrom ctypes.wintypes import HKEY\nfrom ctypes.wintypes import BYTE\n\nNULL = 0\nHDEVINFO = ctypes.c_void_p\nPCTSTR = ctypes.c_char_p\nCHAR = ctypes.c_char\nLPDWORD = PDWORD = ctypes.POINTER(DWORD)\n#~ LPBYTE = PBYTE = ctypes.POINTER(BYTE)\nLPBYTE = PBYTE = ctypes.c_void_p        # XXX avoids error about types\nPHKEY = ctypes.POINTER(HKEY)\n\nACCESS_MASK = DWORD\nREGSAM = ACCESS_MASK\n\n\ndef byte_buffer(length):\n    \"\"\"Get a buffer for a string\"\"\"\n    return (BYTE*length)()\n\ndef string(buffer):\n    s = []\n    for c in buffer:\n        if c == 0: break\n        s.append(chr(c & 0xff)) # \"& 0xff\": hack to convert signed to unsigned\n    return ''.join(s)\n\n\nclass GUID(ctypes.Structure):\n    _fields_ = [\n        ('Data1', DWORD),\n        ('Data2', WORD),\n        ('Data3', WORD),\n        ('Data4', BYTE*8),\n    ]\n    def __str__(self):\n        return \"{%08x-%04x-%04x-%s-%s}\" % (\n            self.Data1,\n            self.Data2,\n            self.Data3,\n            ''.join([\"%02x\" % d for d in self.Data4[:2]]),\n            ''.join([\"%02x\" % d for d in self.Data4[2:]]),\n        )\n\nclass SP_DEVINFO_DATA(ctypes.Structure):\n    _fields_ = [\n        ('cbSize', DWORD),\n        ('ClassGuid', GUID),\n        ('DevInst', DWORD),\n        ('Reserved', ULONG_PTR),\n    ]\n    def __str__(self):\n        return \"ClassGuid:%s DevInst:%s\" % (self.ClassGuid, self.DevInst)\nPSP_DEVINFO_DATA = ctypes.POINTER(SP_DEVINFO_DATA)\n\nclass SP_DEVICE_INTERFACE_DATA(ctypes.Structure):\n    _fields_ = [\n        ('cbSize', DWORD),\n        ('InterfaceClassGuid', GUID),\n        ('Flags', DWORD),\n        ('Reserved', ULONG_PTR),\n    ]\n    def __str__(self):\n        return \"InterfaceClassGuid:%s Flags:%s\" % (self.InterfaceClassGuid, self.Flags)\nPSP_DEVICE_INTERFACE_DATA = ctypes.POINTER(SP_DEVICE_INTERFACE_DATA)\n\nPSP_DEVICE_INTERFACE_DETAIL_DATA = ctypes.c_void_p\n\nsetupapi = ctypes.windll.LoadLibrary(\"setupapi\")\nSetupDiDestroyDeviceInfoList = setupapi.SetupDiDestroyDeviceInfoList\nSetupDiDestroyDeviceInfoList.argtypes = [HDEVINFO]\nSetupDiDestroyDeviceInfoList.restype = BOOL\n\nSetupDiGetClassDevs = setupapi.SetupDiGetClassDevsA\nSetupDiGetClassDevs.argtypes = [ctypes.POINTER(GUID), PCTSTR, HWND, DWORD]\nSetupDiGetClassDevs.restype = HDEVINFO\nSetupDiGetClassDevs.errcheck = ValidHandle\n\nSetupDiEnumDeviceInterfaces = setupapi.SetupDiEnumDeviceInterfaces\nSetupDiEnumDeviceInterfaces.argtypes = [HDEVINFO, PSP_DEVINFO_DATA, ctypes.POINTER(GUID), DWORD, PSP_DEVICE_INTERFACE_DATA]\nSetupDiEnumDeviceInterfaces.restype = BOOL\n\nSetupDiGetDeviceInterfaceDetail = setupapi.SetupDiGetDeviceInterfaceDetailA\nSetupDiGetDeviceInterfaceDetail.argtypes = [HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA, DWORD, PDWORD, PSP_DEVINFO_DATA]\nSetupDiGetDeviceInterfaceDetail.restype = BOOL\n\nSetupDiGetDeviceRegistryProperty = setupapi.SetupDiGetDeviceRegistryPropertyA\nSetupDiGetDeviceRegistryProperty.argtypes = [HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD]\nSetupDiGetDeviceRegistryProperty.restype = BOOL\n\nSetupDiOpenDevRegKey = setupapi.SetupDiOpenDevRegKey\nSetupDiOpenDevRegKey.argtypes = [HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM]\nSetupDiOpenDevRegKey.restype = HKEY\n\nadvapi32 = ctypes.windll.LoadLibrary(\"Advapi32\")\nRegCloseKey = advapi32.RegCloseKey\nRegCloseKey.argtypes = [HKEY]\nRegCloseKey.restype = LONG\n\nRegQueryValueEx = advapi32.RegQueryValueExA\nRegQueryValueEx.argtypes = [HKEY, LPCSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD]\nRegQueryValueEx.restype = LONG\n\n\nGUID_CLASS_COMPORT = GUID(0x86e0d1e0L, 0x8089, 0x11d0,\n    (BYTE*8)(0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73))\n\nDIGCF_PRESENT = 2\nDIGCF_DEVICEINTERFACE = 16\nINVALID_HANDLE_VALUE = 0\nERROR_INSUFFICIENT_BUFFER = 122\nSPDRP_HARDWAREID = 1\nSPDRP_FRIENDLYNAME = 12\nERROR_NO_MORE_ITEMS = 259\nDICS_FLAG_GLOBAL = 1\nDIREG_DEV = 0x00000001\nKEY_READ = 0x20019\nREG_SZ = 1\n\n# workaround for compatibility between Python 2.x and 3.x\nPortName = serial.to_bytes([80, 111, 114, 116, 78, 97, 109, 101]) # \"PortName\"\n\ndef comports():\n    \"\"\"This generator scans the device registry for com ports and yields port, desc, hwid\"\"\"\n    g_hdi = SetupDiGetClassDevs(ctypes.byref(GUID_CLASS_COMPORT), None, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);\n    #~ for i in range(256):\n    for dwIndex in range(256):\n        did = SP_DEVICE_INTERFACE_DATA()\n        did.cbSize = ctypes.sizeof(did)\n\n        if not SetupDiEnumDeviceInterfaces(g_hdi, None, ctypes.byref(GUID_CLASS_COMPORT), dwIndex, ctypes.byref(did)):\n            if ctypes.GetLastError() != ERROR_NO_MORE_ITEMS:\n                raise ctypes.WinError()\n            break\n\n        dwNeeded = DWORD()\n        # get the size\n        if not SetupDiGetDeviceInterfaceDetail(g_hdi, ctypes.byref(did), None, 0, ctypes.byref(dwNeeded), None):\n            # Ignore ERROR_INSUFFICIENT_BUFFER\n            if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:\n                raise ctypes.WinError()\n        # allocate buffer\n        class SP_DEVICE_INTERFACE_DETAIL_DATA_A(ctypes.Structure):\n            _fields_ = [\n                ('cbSize', DWORD),\n                ('DevicePath', CHAR*(dwNeeded.value - ctypes.sizeof(DWORD))),\n            ]\n            def __str__(self):\n                return \"DevicePath:%s\" % (self.DevicePath,)\n        idd = SP_DEVICE_INTERFACE_DETAIL_DATA_A()\n        if is_64bit():\n            idd.cbSize = 8\n        else:\n            idd.cbSize = 5\n        devinfo = SP_DEVINFO_DATA()\n        devinfo.cbSize = ctypes.sizeof(devinfo)\n        if not SetupDiGetDeviceInterfaceDetail(g_hdi, ctypes.byref(did), ctypes.byref(idd), dwNeeded, None, ctypes.byref(devinfo)):\n            raise ctypes.WinError()\n\n        # hardware ID\n        szHardwareID = byte_buffer(250)\n        if not SetupDiGetDeviceRegistryProperty(g_hdi, ctypes.byref(devinfo), SPDRP_HARDWAREID, None, ctypes.byref(szHardwareID), ctypes.sizeof(szHardwareID) - 1, None):\n            # Ignore ERROR_INSUFFICIENT_BUFFER\n            if GetLastError() != ERROR_INSUFFICIENT_BUFFER:\n                raise ctypes.WinError()\n\n        # friendly name\n        szFriendlyName = byte_buffer(250)\n        if not SetupDiGetDeviceRegistryProperty(g_hdi, ctypes.byref(devinfo), SPDRP_FRIENDLYNAME, None, ctypes.byref(szFriendlyName), ctypes.sizeof(szFriendlyName) - 1, None):\n            # Ignore ERROR_INSUFFICIENT_BUFFER\n            if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:\n                #~ raise IOError(\"failed to get details for %s (%s)\" % (devinfo, szHardwareID.value))\n                port_name = None\n        else:\n            # the real com port name has to read differently...\n            hkey = SetupDiOpenDevRegKey(g_hdi, ctypes.byref(devinfo), DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ)\n            port_name_buffer = byte_buffer(250)\n            port_name_length = ULONG(ctypes.sizeof(port_name_buffer))\n            RegQueryValueEx(hkey, PortName, None, None, ctypes.byref(port_name_buffer), ctypes.byref(port_name_length))\n            RegCloseKey(hkey)\n            yield string(port_name_buffer), string(szFriendlyName), string(szHardwareID)\n\n    SetupDiDestroyDeviceInfoList(g_hdi)\n\n\n# test\nif __name__ == '__main__':\n    import serial\n\n    for port, desc, hwid in sorted(comports()):\n        print \"%s: %s [%s]\" % (port, desc, hwid)\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/tools/miniterm.py",
    "content": "#!/usr/bin/env python\n\n# Very simple serial terminal\n# (C)2002-2011 Chris Liechti <cliechti@gmx.net>\n\n# Input characters are sent directly (only LF -> CR/LF/CRLF translation is\n# done), received characters are displayed as is (or escaped trough pythons\n# repr, useful for debug purposes)\n\n\nimport sys, os, serial, threading\n\nEXITCHARCTER = '\\x1d'   # GS/CTRL+]\nMENUCHARACTER = '\\x14'  # Menu: CTRL+T\n\n\ndef key_description(character):\n    \"\"\"generate a readable description for a key\"\"\"\n    ascii_code = ord(character)\n    if ascii_code < 32:\n        return 'Ctrl+%c' % (ord('@') + ascii_code)\n    else:\n        return repr(character)\n\n\n# help text, starts with blank line! it's a function so that the current values\n# for the shortcut keys is used and not the value at program start\ndef get_help_text():\n    return \"\"\"\n--- pySerial (%(version)s) - miniterm - help\n---\n--- %(exit)-8s Exit program\n--- %(menu)-8s Menu escape key, followed by:\n--- Menu keys:\n---    %(itself)-7s Send the menu character itself to remote\n---    %(exchar)-7s Send the exit character itself to remote\n---    %(info)-7s Show info\n---    %(upload)-7s Upload file (prompt will be shown)\n--- Toggles:\n---    %(rts)-7s RTS          %(echo)-7s local echo\n---    %(dtr)-7s DTR          %(break)-7s BREAK\n---    %(lfm)-7s line feed    %(repr)-7s Cycle repr mode\n---\n--- Port settings (%(menu)s followed by the following):\n---    p          change port\n---    7 8        set data bits\n---    n e o s m  change parity (None, Even, Odd, Space, Mark)\n---    1 2 3      set stop bits (1, 2, 1.5)\n---    b          change baud rate\n---    x X        disable/enable software flow control\n---    r R        disable/enable hardware flow control\n\"\"\" % {\n    'version': getattr(serial, 'VERSION', 'unknown version'),\n    'exit': key_description(EXITCHARCTER),\n    'menu': key_description(MENUCHARACTER),\n    'rts': key_description('\\x12'),\n    'repr': key_description('\\x01'),\n    'dtr': key_description('\\x04'),\n    'lfm': key_description('\\x0c'),\n    'break': key_description('\\x02'),\n    'echo': key_description('\\x05'),\n    'info': key_description('\\x09'),\n    'upload': key_description('\\x15'),\n    'itself': key_description(MENUCHARACTER),\n    'exchar': key_description(EXITCHARCTER),\n}\n\nif sys.version_info >= (3, 0):\n    def character(b):\n        return b.decode('latin1')\nelse:\n    def character(b):\n        return b\n\n# first choose a platform dependant way to read single characters from the console\nglobal console\n\nif os.name == 'nt':\n    import msvcrt\n    class Console(object):\n        def __init__(self):\n            pass\n\n        def setup(self):\n            pass    # Do nothing for 'nt'\n\n        def cleanup(self):\n            pass    # Do nothing for 'nt'\n\n        def getkey(self):\n            while True:\n                z = msvcrt.getch()\n                if z == '\\0' or z == '\\xe0':    # functions keys, ignore\n                    msvcrt.getch()\n                else:\n                    if z == '\\r':\n                        return '\\n'\n                    return z\n\n    console = Console()\n\nelif os.name == 'posix':\n    import termios, sys, os\n    class Console(object):\n        def __init__(self):\n            self.fd = sys.stdin.fileno()\n\n        def setup(self):\n            self.old = termios.tcgetattr(self.fd)\n            new = termios.tcgetattr(self.fd)\n            new[3] = new[3] & ~termios.ICANON & ~termios.ECHO & ~termios.ISIG\n            new[6][termios.VMIN] = 1\n            new[6][termios.VTIME] = 0\n            termios.tcsetattr(self.fd, termios.TCSANOW, new)\n\n        def getkey(self):\n            c = os.read(self.fd, 1)\n            return c\n\n        def cleanup(self):\n            termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.old)\n\n    console = Console()\n\n    def cleanup_console():\n        console.cleanup()\n\n    console.setup()\n    sys.exitfunc = cleanup_console      # terminal modes have to be restored on exit...\n\nelse:\n    raise NotImplementedError(\"Sorry no implementation for your platform (%s) available.\" % sys.platform)\n\n\nCONVERT_CRLF = 2\nCONVERT_CR   = 1\nCONVERT_LF   = 0\nNEWLINE_CONVERISON_MAP = ('\\n', '\\r', '\\r\\n')\nLF_MODES = ('LF', 'CR', 'CR/LF')\n\nREPR_MODES = ('raw', 'some control', 'all control', 'hex')\n\nclass Miniterm(object):\n    def __init__(self, port, baudrate, parity, rtscts, xonxoff, echo=False, convert_outgoing=CONVERT_CRLF, repr_mode=0):\n        try:\n            self.serial = serial.serial_for_url(port, baudrate, parity=parity, rtscts=rtscts, xonxoff=xonxoff, timeout=1)\n        except AttributeError:\n            # happens when the installed pyserial is older than 2.5. use the\n            # Serial class directly then.\n            self.serial = serial.Serial(port, baudrate, parity=parity, rtscts=rtscts, xonxoff=xonxoff, timeout=1)\n        self.echo = echo\n        self.repr_mode = repr_mode\n        self.convert_outgoing = convert_outgoing\n        self.newline = NEWLINE_CONVERISON_MAP[self.convert_outgoing]\n        self.dtr_state = True\n        self.rts_state = True\n        self.break_state = False\n\n    def _start_reader(self):\n        \"\"\"Start reader thread\"\"\"\n        self._reader_alive = True\n        # start serial->console thread\n        self.receiver_thread = threading.Thread(target=self.reader)\n        self.receiver_thread.setDaemon(True)\n        self.receiver_thread.start()\n\n    def _stop_reader(self):\n        \"\"\"Stop reader thread only, wait for clean exit of thread\"\"\"\n        self._reader_alive = False\n        self.receiver_thread.join()\n\n\n    def start(self):\n        self.alive = True\n        self._start_reader()\n        # enter console->serial loop\n        self.transmitter_thread = threading.Thread(target=self.writer)\n        self.transmitter_thread.setDaemon(True)\n        self.transmitter_thread.start()\n\n    def stop(self):\n        self.alive = False\n\n    def join(self, transmit_only=False):\n        self.transmitter_thread.join()\n        if not transmit_only:\n            self.receiver_thread.join()\n\n    def dump_port_settings(self):\n        sys.stderr.write(\"\\n--- Settings: %s  %s,%s,%s,%s\\n\" % (\n                self.serial.portstr,\n                self.serial.baudrate,\n                self.serial.bytesize,\n                self.serial.parity,\n                self.serial.stopbits))\n        sys.stderr.write('--- RTS: %-8s  DTR: %-8s  BREAK: %-8s\\n' % (\n                (self.rts_state and 'active' or 'inactive'),\n                (self.dtr_state and 'active' or 'inactive'),\n                (self.break_state and 'active' or 'inactive')))\n        try:\n            sys.stderr.write('--- CTS: %-8s  DSR: %-8s  RI: %-8s  CD: %-8s\\n' % (\n                    (self.serial.getCTS() and 'active' or 'inactive'),\n                    (self.serial.getDSR() and 'active' or 'inactive'),\n                    (self.serial.getRI() and 'active' or 'inactive'),\n                    (self.serial.getCD() and 'active' or 'inactive')))\n        except serial.SerialException:\n            # on RFC 2217 ports it can happen to no modem state notification was\n            # yet received. ignore this error.\n            pass\n        sys.stderr.write('--- software flow control: %s\\n' % (self.serial.xonxoff and 'active' or 'inactive'))\n        sys.stderr.write('--- hardware flow control: %s\\n' % (self.serial.rtscts and 'active' or 'inactive'))\n        sys.stderr.write('--- data escaping: %s  linefeed: %s\\n' % (\n                REPR_MODES[self.repr_mode],\n                LF_MODES[self.convert_outgoing]))\n\n    def reader(self):\n        \"\"\"loop and copy serial->console\"\"\"\n        try:\n            while self.alive and self._reader_alive:\n                data = character(self.serial.read(1))\n\n                if self.repr_mode == 0:\n                    # direct output, just have to care about newline setting\n                    if data == '\\r' and self.convert_outgoing == CONVERT_CR:\n                        sys.stdout.write('\\n')\n                    else:\n                        sys.stdout.write(data)\n                elif self.repr_mode == 1:\n                    # escape non-printable, let pass newlines\n                    if self.convert_outgoing == CONVERT_CRLF and data in '\\r\\n':\n                        if data == '\\n':\n                            sys.stdout.write('\\n')\n                        elif data == '\\r':\n                            pass\n                    elif data == '\\n' and self.convert_outgoing == CONVERT_LF:\n                        sys.stdout.write('\\n')\n                    elif data == '\\r' and self.convert_outgoing == CONVERT_CR:\n                        sys.stdout.write('\\n')\n                    else:\n                        sys.stdout.write(repr(data)[1:-1])\n                elif self.repr_mode == 2:\n                    # escape all non-printable, including newline\n                    sys.stdout.write(repr(data)[1:-1])\n                elif self.repr_mode == 3:\n                    # escape everything (hexdump)\n                    for c in data:\n                        sys.stdout.write(\"%s \" % c.encode('hex'))\n                sys.stdout.flush()\n        except serial.SerialException, e:\n            self.alive = False\n            # would be nice if the console reader could be interruptted at this\n            # point...\n            raise\n\n\n    def writer(self):\n        \"\"\"\\\n        Loop and copy console->serial until EXITCHARCTER character is\n        found. When MENUCHARACTER is found, interpret the next key\n        locally.\n        \"\"\"\n        menu_active = False\n        try:\n            while self.alive:\n                try:\n                    b = console.getkey()\n                except KeyboardInterrupt:\n                    b = serial.to_bytes([3])\n                c = character(b)\n                if menu_active:\n                    if c == MENUCHARACTER or c == EXITCHARCTER: # Menu character again/exit char -> send itself\n                        self.serial.write(b)                    # send character\n                        if self.echo:\n                            sys.stdout.write(c)\n                    elif c == '\\x15':                       # CTRL+U -> upload file\n                        sys.stderr.write('\\n--- File to upload: ')\n                        sys.stderr.flush()\n                        console.cleanup()\n                        filename = sys.stdin.readline().rstrip('\\r\\n')\n                        if filename:\n                            try:\n                                file = open(filename, 'r')\n                                sys.stderr.write('--- Sending file %s ---\\n' % filename)\n                                while True:\n                                    line = file.readline().rstrip('\\r\\n')\n                                    if not line:\n                                        break\n                                    self.serial.write(line)\n                                    self.serial.write('\\r\\n')\n                                    # Wait for output buffer to drain.\n                                    self.serial.flush()\n                                    sys.stderr.write('.')   # Progress indicator.\n                                sys.stderr.write('\\n--- File %s sent ---\\n' % filename)\n                            except IOError, e:\n                                sys.stderr.write('--- ERROR opening file %s: %s ---\\n' % (filename, e))\n                        console.setup()\n                    elif c in '\\x08hH?':                    # CTRL+H, h, H, ? -> Show help\n                        sys.stderr.write(get_help_text())\n                    elif c == '\\x12':                       # CTRL+R -> Toggle RTS\n                        self.rts_state = not self.rts_state\n                        self.serial.setRTS(self.rts_state)\n                        sys.stderr.write('--- RTS %s ---\\n' % (self.rts_state and 'active' or 'inactive'))\n                    elif c == '\\x04':                       # CTRL+D -> Toggle DTR\n                        self.dtr_state = not self.dtr_state\n                        self.serial.setDTR(self.dtr_state)\n                        sys.stderr.write('--- DTR %s ---\\n' % (self.dtr_state and 'active' or 'inactive'))\n                    elif c == '\\x02':                       # CTRL+B -> toggle BREAK condition\n                        self.break_state = not self.break_state\n                        self.serial.setBreak(self.break_state)\n                        sys.stderr.write('--- BREAK %s ---\\n' % (self.break_state and 'active' or 'inactive'))\n                    elif c == '\\x05':                       # CTRL+E -> toggle local echo\n                        self.echo = not self.echo\n                        sys.stderr.write('--- local echo %s ---\\n' % (self.echo and 'active' or 'inactive'))\n                    elif c == '\\x09':                       # CTRL+I -> info\n                        self.dump_port_settings()\n                    elif c == '\\x01':                       # CTRL+A -> cycle escape mode\n                        self.repr_mode += 1\n                        if self.repr_mode > 3:\n                            self.repr_mode = 0\n                        sys.stderr.write('--- escape data: %s ---\\n' % (\n                            REPR_MODES[self.repr_mode],\n                        ))\n                    elif c == '\\x0c':                       # CTRL+L -> cycle linefeed mode\n                        self.convert_outgoing += 1\n                        if self.convert_outgoing > 2:\n                            self.convert_outgoing = 0\n                        self.newline = NEWLINE_CONVERISON_MAP[self.convert_outgoing]\n                        sys.stderr.write('--- line feed %s ---\\n' % (\n                            LF_MODES[self.convert_outgoing],\n                        ))\n                    elif c in 'pP':                         # P -> change port\n                        sys.stderr.write('\\n--- Enter port name: ')\n                        sys.stderr.flush()\n                        console.cleanup()\n                        try:\n                            port = sys.stdin.readline().strip()\n                        except KeyboardInterrupt:\n                            port = None\n                        console.setup()\n                        if port and port != self.serial.port:\n                            # reader thread needs to be shut down\n                            self._stop_reader()\n                            # save settings\n                            settings = self.serial.getSettingsDict()\n                            try:\n                                try:\n                                    new_serial = serial.serial_for_url(port, do_not_open=True)\n                                except AttributeError:\n                                    # happens when the installed pyserial is older than 2.5. use the\n                                    # Serial class directly then.\n                                    new_serial = serial.Serial()\n                                    new_serial.port = port\n                                # restore settings and open\n                                new_serial.applySettingsDict(settings)\n                                new_serial.open()\n                                new_serial.setRTS(self.rts_state)\n                                new_serial.setDTR(self.dtr_state)\n                                new_serial.setBreak(self.break_state)\n                            except Exception, e:\n                                sys.stderr.write('--- ERROR opening new port: %s ---\\n' % (e,))\n                                new_serial.close()\n                            else:\n                                self.serial.close()\n                                self.serial = new_serial\n                                sys.stderr.write('--- Port changed to: %s ---\\n' % (self.serial.port,))\n                            # and restart the reader thread\n                            self._start_reader()\n                    elif c in 'bB':                         # B -> change baudrate\n                        sys.stderr.write('\\n--- Baudrate: ')\n                        sys.stderr.flush()\n                        console.cleanup()\n                        backup = self.serial.baudrate\n                        try:\n                            self.serial.baudrate = int(sys.stdin.readline().strip())\n                        except ValueError, e:\n                            sys.stderr.write('--- ERROR setting baudrate: %s ---\\n' % (e,))\n                            self.serial.baudrate = backup\n                        else:\n                            self.dump_port_settings()\n                        console.setup()\n                    elif c == '8':                          # 8 -> change to 8 bits\n                        self.serial.bytesize = serial.EIGHTBITS\n                        self.dump_port_settings()\n                    elif c == '7':                          # 7 -> change to 8 bits\n                        self.serial.bytesize = serial.SEVENBITS\n                        self.dump_port_settings()\n                    elif c in 'eE':                         # E -> change to even parity\n                        self.serial.parity = serial.PARITY_EVEN\n                        self.dump_port_settings()\n                    elif c in 'oO':                         # O -> change to odd parity\n                        self.serial.parity = serial.PARITY_ODD\n                        self.dump_port_settings()\n                    elif c in 'mM':                         # M -> change to mark parity\n                        self.serial.parity = serial.PARITY_MARK\n                        self.dump_port_settings()\n                    elif c in 'sS':                         # S -> change to space parity\n                        self.serial.parity = serial.PARITY_SPACE\n                        self.dump_port_settings()\n                    elif c in 'nN':                         # N -> change to no parity\n                        self.serial.parity = serial.PARITY_NONE\n                        self.dump_port_settings()\n                    elif c == '1':                          # 1 -> change to 1 stop bits\n                        self.serial.stopbits = serial.STOPBITS_ONE\n                        self.dump_port_settings()\n                    elif c == '2':                          # 2 -> change to 2 stop bits\n                        self.serial.stopbits = serial.STOPBITS_TWO\n                        self.dump_port_settings()\n                    elif c == '3':                          # 3 -> change to 1.5 stop bits\n                        self.serial.stopbits = serial.STOPBITS_ONE_POINT_FIVE\n                        self.dump_port_settings()\n                    elif c in 'xX':                         # X -> change software flow control\n                        self.serial.xonxoff = (c == 'X')\n                        self.dump_port_settings()\n                    elif c in 'rR':                         # R -> change hardware flow control\n                        self.serial.rtscts = (c == 'R')\n                        self.dump_port_settings()\n                    else:\n                        sys.stderr.write('--- unknown menu character %s --\\n' % key_description(c))\n                    menu_active = False\n                elif c == MENUCHARACTER: # next char will be for menu\n                    menu_active = True\n                elif c == EXITCHARCTER: \n                    self.stop()\n                    break                                   # exit app\n                elif c == '\\n':\n                    self.serial.write(self.newline)         # send newline character(s)\n                    if self.echo:\n                        sys.stdout.write(c)                 # local echo is a real newline in any case\n                        sys.stdout.flush()\n                else:\n                    self.serial.write(b)                    # send byte\n                    if self.echo:\n                        sys.stdout.write(c)\n                        sys.stdout.flush()\n        except:\n            self.alive = False\n            raise\n\ndef main():\n    import optparse\n\n    parser = optparse.OptionParser(\n        usage = \"%prog [options] [port [baudrate]]\",\n        description = \"Miniterm - A simple terminal program for the serial port.\"\n    )\n\n    parser.add_option(\"-p\", \"--port\",\n        dest = \"port\",\n        help = \"port, a number or a device name. (deprecated option, use parameter instead)\",\n        default = None\n    )\n\n    parser.add_option(\"-b\", \"--baud\",\n        dest = \"baudrate\",\n        action = \"store\",\n        type = 'int',\n        help = \"set baud rate, default %default\",\n        default = 9600\n    )\n\n    parser.add_option(\"--parity\",\n        dest = \"parity\",\n        action = \"store\",\n        help = \"set parity, one of [N, E, O, S, M], default=N\",\n        default = 'N'\n    )\n\n    parser.add_option(\"-e\", \"--echo\",\n        dest = \"echo\",\n        action = \"store_true\",\n        help = \"enable local echo (default off)\",\n        default = False\n    )\n\n    parser.add_option(\"--rtscts\",\n        dest = \"rtscts\",\n        action = \"store_true\",\n        help = \"enable RTS/CTS flow control (default off)\",\n        default = False\n    )\n\n    parser.add_option(\"--xonxoff\",\n        dest = \"xonxoff\",\n        action = \"store_true\",\n        help = \"enable software flow control (default off)\",\n        default = False\n    )\n\n    parser.add_option(\"--cr\",\n        dest = \"cr\",\n        action = \"store_true\",\n        help = \"do not send CR+LF, send CR only\",\n        default = False\n    )\n\n    parser.add_option(\"--lf\",\n        dest = \"lf\",\n        action = \"store_true\",\n        help = \"do not send CR+LF, send LF only\",\n        default = False\n    )\n\n    parser.add_option(\"-D\", \"--debug\",\n        dest = \"repr_mode\",\n        action = \"count\",\n        help = \"\"\"debug received data (escape non-printable chars)\n--debug can be given multiple times:\n0: just print what is received\n1: escape non-printable characters, do newlines as unusual\n2: escape non-printable characters, newlines too\n3: hex dump everything\"\"\",\n        default = 0\n    )\n\n    parser.add_option(\"--rts\",\n        dest = \"rts_state\",\n        action = \"store\",\n        type = 'int',\n        help = \"set initial RTS line state (possible values: 0, 1)\",\n        default = None\n    )\n\n    parser.add_option(\"--dtr\",\n        dest = \"dtr_state\",\n        action = \"store\",\n        type = 'int',\n        help = \"set initial DTR line state (possible values: 0, 1)\",\n        default = None\n    )\n\n    parser.add_option(\"-q\", \"--quiet\",\n        dest = \"quiet\",\n        action = \"store_true\",\n        help = \"suppress non error messages\",\n        default = False\n    )\n\n    parser.add_option(\"--exit-char\",\n        dest = \"exit_char\",\n        action = \"store\",\n        type = 'int',\n        help = \"ASCII code of special character that is used to exit the application\",\n        default = 0x1d\n    )\n\n    parser.add_option(\"--menu-char\",\n        dest = \"menu_char\",\n        action = \"store\",\n        type = 'int',\n        help = \"ASCII code of special character that is used to control miniterm (menu)\",\n        default = 0x14\n    )\n\n    (options, args) = parser.parse_args()\n\n    options.parity = options.parity.upper()\n    if options.parity not in 'NEOSM':\n        parser.error(\"invalid parity\")\n\n    if options.cr and options.lf:\n        parser.error(\"only one of --cr or --lf can be specified\")\n\n    if options.menu_char == options.exit_char:\n        parser.error('--exit-char can not be the same as --menu-char')\n\n    global EXITCHARCTER, MENUCHARACTER\n    EXITCHARCTER = chr(options.exit_char)\n    MENUCHARACTER = chr(options.menu_char)\n\n    port = options.port\n    baudrate = options.baudrate\n    if args:\n        if options.port is not None:\n            parser.error(\"no arguments are allowed, options only when --port is given\")\n        port = args.pop(0)\n        if args:\n            try:\n                baudrate = int(args[0])\n            except ValueError:\n                parser.error(\"baud rate must be a number, not %r\" % args[0])\n            args.pop(0)\n        if args:\n            parser.error(\"too many arguments\")\n    else:\n        if port is None: port = 0\n\n    convert_outgoing = CONVERT_CRLF\n    if options.cr:\n        convert_outgoing = CONVERT_CR\n    elif options.lf:\n        convert_outgoing = CONVERT_LF\n\n    try:\n        miniterm = Miniterm(\n            port,\n            baudrate,\n            options.parity,\n            rtscts=options.rtscts,\n            xonxoff=options.xonxoff,\n            echo=options.echo,\n            convert_outgoing=convert_outgoing,\n            repr_mode=options.repr_mode,\n        )\n    except serial.SerialException, e:\n        sys.stderr.write(\"could not open port %r: %s\\n\" % (port, e))\n        sys.exit(1)\n\n    if not options.quiet:\n        sys.stderr.write('--- Miniterm on %s: %d,%s,%s,%s ---\\n' % (\n            miniterm.serial.portstr,\n            miniterm.serial.baudrate,\n            miniterm.serial.bytesize,\n            miniterm.serial.parity,\n            miniterm.serial.stopbits,\n        ))\n        sys.stderr.write('--- Quit: %s  |  Menu: %s | Help: %s followed by %s ---\\n' % (\n            key_description(EXITCHARCTER),\n            key_description(MENUCHARACTER),\n            key_description(MENUCHARACTER),\n            key_description('\\x08'),\n        ))\n\n    if options.dtr_state is not None:\n        if not options.quiet:\n            sys.stderr.write('--- forcing DTR %s\\n' % (options.dtr_state and 'active' or 'inactive'))\n        miniterm.serial.setDTR(options.dtr_state)\n        miniterm.dtr_state = options.dtr_state\n    if options.rts_state is not None:\n        if not options.quiet:\n            sys.stderr.write('--- forcing RTS %s\\n' % (options.rts_state and 'active' or 'inactive'))\n        miniterm.serial.setRTS(options.rts_state)\n        miniterm.rts_state = options.rts_state\n\n    miniterm.start()\n    try:\n        miniterm.join(True)\n    except KeyboardInterrupt:\n        pass\n    if not options.quiet:\n        sys.stderr.write(\"\\n--- exit ---\\n\")\n    miniterm.join()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/urlhandler/__init__.py",
    "content": ""
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/urlhandler/protocol_hwgrep.py",
    "content": "#! python\n#\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# see __init__.py\n#\n# This module implements a special URL handler that uses the port listing to\n# find ports by searching the string descriptions.\n#\n# (C) 2011 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n#\n# URL format:    hwgrep://regexp\n\nimport serial\nimport serial.tools.list_ports\n\nclass Serial(serial.Serial):\n    \"\"\"Just inherit the native Serial port implementation and patch the open function.\"\"\"\n\n    def setPort(self, value):\n        \"\"\"translate port name before storing it\"\"\"\n        if isinstance(value, basestring) and value.startswith('hwgrep://'):\n            serial.Serial.setPort(self, self.fromURL(value))\n        else:\n            serial.Serial.setPort(self, value)\n\n    def fromURL(self, url):\n        \"\"\"extract host and port from an URL string\"\"\"\n        if url.lower().startswith(\"hwgrep://\"): url = url[9:]\n        # use a for loop to get the 1st element from the generator\n        for port, desc, hwid in serial.tools.list_ports.grep(url):\n            return port\n        else:\n            raise serial.SerialException('no ports found matching regexp %r' % (url,))\n\n    # override property\n    port = property(serial.Serial.getPort, setPort, doc=\"Port setting\")\n\n# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\nif __name__ == '__main__':\n    #~ s = Serial('hwgrep://ttyS0')\n    s = Serial(None)\n    s.port = 'hwgrep://ttyS0'\n    print s\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/urlhandler/protocol_loop.py",
    "content": "#! python\n#\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# see __init__.py\n#\n# This module implements a loop back connection receiving itself what it sent.\n#\n# The purpose of this module is.. well... You can run the unit tests with it.\n# and it was so easy to implement ;-)\n#\n# (C) 2001-2011 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n#\n# URL format:    loop://[option[/option...]]\n# options:\n# - \"debug\" print diagnostic messages\n\nfrom serial.serialutil import *\nimport threading\nimport time\nimport logging\n\n# map log level names to constants. used in fromURL()\nLOGGER_LEVELS = {\n    'debug': logging.DEBUG,\n    'info': logging.INFO,\n    'warning': logging.WARNING,\n    'error': logging.ERROR,\n    }\n\n\nclass LoopbackSerial(SerialBase):\n    \"\"\"Serial port implementation that simulates a loop back connection in plain software.\"\"\"\n\n    BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,\n                 9600, 19200, 38400, 57600, 115200)\n\n    def open(self):\n        \"\"\"Open port with current settings. This may throw a SerialException\n           if the port cannot be opened.\"\"\"\n        if self._isOpen:\n            raise SerialException(\"Port is already open.\")\n        self.logger = None\n        self.buffer_lock = threading.Lock()\n        self.loop_buffer = bytearray()\n        self.cts = False\n        self.dsr = False\n\n        if self._port is None:\n            raise SerialException(\"Port must be configured before it can be used.\")\n        # not that there is anything to open, but the function applies the\n        # options found in the URL\n        self.fromURL(self.port)\n\n        # not that there anything to configure...\n        self._reconfigurePort()\n        # all things set up get, now a clean start\n        self._isOpen = True\n        if not self._rtscts:\n            self.setRTS(True)\n            self.setDTR(True)\n        self.flushInput()\n        self.flushOutput()\n\n    def _reconfigurePort(self):\n        \"\"\"Set communication parameters on opened port. for the loop://\n        protocol all settings are ignored!\"\"\"\n        # not that's it of any real use, but it helps in the unit tests\n        if not isinstance(self._baudrate, (int, long)) or not 0 < self._baudrate < 2**32:\n            raise ValueError(\"invalid baudrate: %r\" % (self._baudrate))\n        if self.logger:\n            self.logger.info('_reconfigurePort()')\n\n    def close(self):\n        \"\"\"Close port\"\"\"\n        if self._isOpen:\n            self._isOpen = False\n            # in case of quick reconnects, give the server some time\n            time.sleep(0.3)\n\n    def makeDeviceName(self, port):\n        raise SerialException(\"there is no sensible way to turn numbers into URLs\")\n\n    def fromURL(self, url):\n        \"\"\"extract host and port from an URL string\"\"\"\n        if url.lower().startswith(\"loop://\"): url = url[7:]\n        try:\n            # process options now, directly altering self\n            for option in url.split('/'):\n                if '=' in option:\n                    option, value = option.split('=', 1)\n                else:\n                    value = None\n                if not option:\n                    pass\n                elif option == 'logging':\n                    logging.basicConfig()   # XXX is that good to call it here?\n                    self.logger = logging.getLogger('pySerial.loop')\n                    self.logger.setLevel(LOGGER_LEVELS[value])\n                    self.logger.debug('enabled logging')\n                else:\n                    raise ValueError('unknown option: %r' % (option,))\n        except ValueError, e:\n            raise SerialException('expected a string in the form \"[loop://][option[/option...]]\": %s' % e)\n\n    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n\n    def inWaiting(self):\n        \"\"\"Return the number of characters currently in the input buffer.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            # attention the logged value can differ from return value in\n            # threaded environments...\n            self.logger.debug('inWaiting() -> %d' % (len(self.loop_buffer),))\n        return len(self.loop_buffer)\n\n    def read(self, size=1):\n        \"\"\"Read size bytes from the serial port. If a timeout is set it may\n        return less characters as requested. With no timeout it will block\n        until the requested number of bytes is read.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self._timeout is not None:\n            timeout = time.time() + self._timeout\n        else:\n            timeout = None\n        data = bytearray()\n        while size > 0:\n            self.buffer_lock.acquire()\n            try:\n                block = to_bytes(self.loop_buffer[:size])\n                del self.loop_buffer[:size]\n            finally:\n                self.buffer_lock.release()\n            data += block\n            size -= len(block)\n            # check for timeout now, after data has been read.\n            # useful for timeout = 0 (non blocking) read\n            if timeout and time.time() > timeout:\n                break\n        return bytes(data)\n\n    def write(self, data):\n        \"\"\"Output the given string over the serial port. Can block if the\n        connection is blocked. May raise SerialException if the connection is\n        closed.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        # ensure we're working with bytes\n        data = bytes(data)\n        # calculate aprox time that would be used to send the data\n        time_used_to_send = 10.0*len(data) / self._baudrate\n        # when a write timeout is configured check if we would be successful\n        # (not sending anything, not even the part that would have time)\n        if self._writeTimeout is not None and time_used_to_send > self._writeTimeout:\n            time.sleep(self._writeTimeout) # must wait so that unit test succeeds\n            raise writeTimeoutError\n        self.buffer_lock.acquire()\n        try:\n            self.loop_buffer += data\n        finally:\n            self.buffer_lock.release()\n        return len(data)\n\n    def flushInput(self):\n        \"\"\"Clear input buffer, discarding all that is in the buffer.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('flushInput()')\n        self.buffer_lock.acquire()\n        try:\n            del self.loop_buffer[:]\n        finally:\n            self.buffer_lock.release()\n\n    def flushOutput(self):\n        \"\"\"Clear output buffer, aborting the current output and\n        discarding all that is in the buffer.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('flushOutput()')\n\n    def sendBreak(self, duration=0.25):\n        \"\"\"Send break condition. Timed, returns to idle state after given\n        duration.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n\n    def setBreak(self, level=True):\n        \"\"\"Set break: Controls TXD. When active, to transmitting is\n        possible.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('setBreak(%r)' % (level,))\n\n    def setRTS(self, level=True):\n        \"\"\"Set terminal status line: Request To Send\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('setRTS(%r) -> state of CTS' % (level,))\n        self.cts = level\n\n    def setDTR(self, level=True):\n        \"\"\"Set terminal status line: Data Terminal Ready\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('setDTR(%r) -> state of DSR' % (level,))\n        self.dsr = level\n\n    def getCTS(self):\n        \"\"\"Read terminal status line: Clear To Send\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('getCTS() -> state of RTS (%r)' % (self.cts,))\n        return self.cts\n\n    def getDSR(self):\n        \"\"\"Read terminal status line: Data Set Ready\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('getDSR() -> state of DTR (%r)' % (self.dsr,))\n        return self.dsr\n\n    def getRI(self):\n        \"\"\"Read terminal status line: Ring Indicator\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('returning dummy for getRI()')\n        return False\n\n    def getCD(self):\n        \"\"\"Read terminal status line: Carrier Detect\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('returning dummy for getCD()')\n        return True\n\n    # - - - platform specific - - -\n    # None so far\n\n\n# assemble Serial class with the platform specific implementation and the base\n# for file-like behavior. for Python 2.6 and newer, that provide the new I/O\n# library, derive from io.RawIOBase\ntry:\n    import io\nexcept ImportError:\n    # classic version with our own file-like emulation\n    class Serial(LoopbackSerial, FileLike):\n        pass\nelse:\n    # io library present\n    class Serial(LoopbackSerial, io.RawIOBase):\n        pass\n\n\n# simple client test\nif __name__ == '__main__':\n    import sys\n    s = Serial('loop://')\n    sys.stdout.write('%s\\n' % s)\n\n    sys.stdout.write(\"write...\\n\")\n    s.write(\"hello\\n\")\n    s.flush()\n    sys.stdout.write(\"read: %s\\n\" % s.read(5))\n\n    s.close()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/urlhandler/protocol_rfc2217.py",
    "content": "#! python\n#\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# see ../__init__.py\n#\n# This is a thin wrapper to load the rfc2271 implementation.\n#\n# (C) 2011 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n\nfrom serial.rfc2217 import Serial\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/urlhandler/protocol_socket.py",
    "content": "#! python\n#\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# see __init__.py\n#\n# This module implements a simple socket based client.\n# It does not support changing any port parameters and will silently ignore any\n# requests to do so.\n#\n# The purpose of this module is that applications using pySerial can connect to\n# TCP/IP to serial port converters that do not support RFC 2217.\n#\n# (C) 2001-2011 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n#\n# URL format:    socket://<host>:<port>[/option[/option...]]\n# options:\n# - \"debug\" print diagnostic messages\n\nfrom serial.serialutil import *\nimport time\nimport socket\nimport logging\n\n# map log level names to constants. used in fromURL()\nLOGGER_LEVELS = {\n    'debug': logging.DEBUG,\n    'info': logging.INFO,\n    'warning': logging.WARNING,\n    'error': logging.ERROR,\n    }\n\n\nclass SocketSerial(SerialBase):\n    \"\"\"Serial port implementation for plain sockets.\"\"\"\n\n    BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,\n                 9600, 19200, 38400, 57600, 115200)\n\n    def open(self):\n        \"\"\"Open port with current settings. This may throw a SerialException\n           if the port cannot be opened.\"\"\"\n        self.logger = None\n        if self._port is None:\n            raise SerialException(\"Port must be configured before it can be used.\")\n        if self._isOpen:\n            raise SerialException(\"Port is already open.\")\n        try:\n            self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n            self._socket.connect(self.fromURL(self.portstr))\n        except Exception, msg:\n            self._socket = None\n            raise SerialException(\"Could not open port %s: %s\" % (self.portstr, msg))\n\n        self._socket.settimeout(2) # used for write timeout support :/\n\n        # not that there anything to configure...\n        self._reconfigurePort()\n        # all things set up get, now a clean start\n        self._isOpen = True\n        if not self._rtscts:\n            self.setRTS(True)\n            self.setDTR(True)\n        self.flushInput()\n        self.flushOutput()\n\n    def _reconfigurePort(self):\n        \"\"\"Set communication parameters on opened port. for the socket://\n        protocol all settings are ignored!\"\"\"\n        if self._socket is None:\n            raise SerialException(\"Can only operate on open ports\")\n        if self.logger:\n            self.logger.info('ignored port configuration change')\n\n    def close(self):\n        \"\"\"Close port\"\"\"\n        if self._isOpen:\n            if self._socket:\n                try:\n                    self._socket.shutdown(socket.SHUT_RDWR)\n                    self._socket.close()\n                except:\n                    # ignore errors.\n                    pass\n                self._socket = None\n            self._isOpen = False\n            # in case of quick reconnects, give the server some time\n            time.sleep(0.3)\n\n    def makeDeviceName(self, port):\n        raise SerialException(\"there is no sensible way to turn numbers into URLs\")\n\n    def fromURL(self, url):\n        \"\"\"extract host and port from an URL string\"\"\"\n        if url.lower().startswith(\"socket://\"): url = url[9:]\n        try:\n            # is there a \"path\" (our options)?\n            if '/' in url:\n                # cut away options\n                url, options = url.split('/', 1)\n                # process options now, directly altering self\n                for option in options.split('/'):\n                    if '=' in option:\n                        option, value = option.split('=', 1)\n                    else:\n                        value = None\n                    if option == 'logging':\n                        logging.basicConfig()   # XXX is that good to call it here?\n                        self.logger = logging.getLogger('pySerial.socket')\n                        self.logger.setLevel(LOGGER_LEVELS[value])\n                        self.logger.debug('enabled logging')\n                    else:\n                        raise ValueError('unknown option: %r' % (option,))\n            # get host and port\n            host, port = url.split(':', 1) # may raise ValueError because of unpacking\n            port = int(port)               # and this if it's not a number\n            if not 0 <= port < 65536: raise ValueError(\"port not in range 0...65535\")\n        except ValueError, e:\n            raise SerialException('expected a string in the form \"[rfc2217://]<host>:<port>[/option[/option...]]\": %s' % e)\n        return (host, port)\n\n    #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -\n\n    def inWaiting(self):\n        \"\"\"Return the number of characters currently in the input buffer.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            # set this one to debug as the function could be called often...\n            self.logger.debug('WARNING: inWaiting returns dummy value')\n        return 0 # hmmm, see comment in read()\n\n    def read(self, size=1):\n        \"\"\"Read size bytes from the serial port. If a timeout is set it may\n        return less characters as requested. With no timeout it will block\n        until the requested number of bytes is read.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        data = bytearray()\n        timeout = time.time() + self._timeout\n        while len(data) < size and time.time() < timeout:\n            try:\n                # an implementation with internal buffer would be better\n                # performing...\n                data = self._socket.recv(size - len(data))\n            except socket.timeout:\n                # just need to get out of recv form time to time to check if\n                # still alive\n                continue\n            except socket.error, e:\n                # connection fails -> terminate loop\n                raise SerialException('connection failed (%s)' % e)\n        return bytes(data)\n\n    def write(self, data):\n        \"\"\"Output the given string over the serial port. Can block if the\n        connection is blocked. May raise SerialException if the connection is\n        closed.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        try:\n            self._socket.sendall(data)\n        except socket.error, e:\n            raise SerialException(\"socket connection failed: %s\" % e) # XXX what exception if socket connection fails\n        return len(data)\n\n    def flushInput(self):\n        \"\"\"Clear input buffer, discarding all that is in the buffer.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('ignored flushInput')\n\n    def flushOutput(self):\n        \"\"\"Clear output buffer, aborting the current output and\n        discarding all that is in the buffer.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('ignored flushOutput')\n\n    def sendBreak(self, duration=0.25):\n        \"\"\"Send break condition. Timed, returns to idle state after given\n        duration.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('ignored sendBreak(%r)' % (duration,))\n\n    def setBreak(self, level=True):\n        \"\"\"Set break: Controls TXD. When active, to transmitting is\n        possible.\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('ignored setBreak(%r)' % (level,))\n\n    def setRTS(self, level=True):\n        \"\"\"Set terminal status line: Request To Send\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('ignored setRTS(%r)' % (level,))\n\n    def setDTR(self, level=True):\n        \"\"\"Set terminal status line: Data Terminal Ready\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('ignored setDTR(%r)' % (level,))\n\n    def getCTS(self):\n        \"\"\"Read terminal status line: Clear To Send\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('returning dummy for getCTS()')\n        return True\n\n    def getDSR(self):\n        \"\"\"Read terminal status line: Data Set Ready\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('returning dummy for getDSR()')\n        return True\n\n    def getRI(self):\n        \"\"\"Read terminal status line: Ring Indicator\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('returning dummy for getRI()')\n        return False\n\n    def getCD(self):\n        \"\"\"Read terminal status line: Carrier Detect\"\"\"\n        if not self._isOpen: raise portNotOpenError\n        if self.logger:\n            self.logger.info('returning dummy for getCD()')\n        return True\n\n    # - - - platform specific - - -\n    # None so far\n\n\n# assemble Serial class with the platform specific implementation and the base\n# for file-like behavior. for Python 2.6 and newer, that provide the new I/O\n# library, derive from io.RawIOBase\ntry:\n    import io\nexcept ImportError:\n    # classic version with our own file-like emulation\n    class Serial(SocketSerial, FileLike):\n        pass\nelse:\n    # io library present\n    class Serial(SocketSerial, io.RawIOBase):\n        pass\n\n\n# simple client test\nif __name__ == '__main__':\n    import sys\n    s = Serial('socket://localhost:7000')\n    sys.stdout.write('%s\\n' % s)\n\n    sys.stdout.write(\"write...\\n\")\n    s.write(\"hello\\n\")\n    s.flush()\n    sys.stdout.write(\"read: %s\\n\" % s.read(5))\n\n    s.close()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/serial/win32.py",
    "content": "from ctypes import *\nfrom ctypes.wintypes import HANDLE\nfrom ctypes.wintypes import BOOL\nfrom ctypes.wintypes import LPCWSTR\n_stdcall_libraries = {}\n_stdcall_libraries['kernel32'] = WinDLL('kernel32')\nfrom ctypes.wintypes import DWORD\nfrom ctypes.wintypes import WORD\nfrom ctypes.wintypes import BYTE\n\nINVALID_HANDLE_VALUE = HANDLE(-1).value\n\n# some details of the windows API differ between 32 and 64 bit systems..\ndef is_64bit():\n    \"\"\"Returns true when running on a 64 bit system\"\"\"\n    return sizeof(c_ulong) != sizeof(c_void_p)\n\n# ULONG_PTR is a an ordinary number, not a pointer and contrary to the name it\n# is either 32 or 64 bits, depending on the type of windows...\n# so test if this a 32 bit windows...\nif is_64bit():\n    # assume 64 bits\n    ULONG_PTR = c_int64\nelse:\n    # 32 bits\n    ULONG_PTR = c_ulong\n\n\nclass _SECURITY_ATTRIBUTES(Structure):\n    pass\nLPSECURITY_ATTRIBUTES = POINTER(_SECURITY_ATTRIBUTES)\n\n\ntry:\n    CreateEventW = _stdcall_libraries['kernel32'].CreateEventW\nexcept AttributeError:\n    # Fallback to non wide char version for old OS...\n    from ctypes.wintypes import LPCSTR\n    CreateEventA = _stdcall_libraries['kernel32'].CreateEventA\n    CreateEventA.restype = HANDLE\n    CreateEventA.argtypes = [LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCSTR]\n    CreateEvent=CreateEventA\n\n    CreateFileA = _stdcall_libraries['kernel32'].CreateFileA\n    CreateFileA.restype = HANDLE\n    CreateFileA.argtypes = [LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE]\n    CreateFile = CreateFileA\nelse:\n    CreateEventW.restype = HANDLE\n    CreateEventW.argtypes = [LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCWSTR]\n    CreateEvent = CreateEventW # alias\n\n    CreateFileW = _stdcall_libraries['kernel32'].CreateFileW\n    CreateFileW.restype = HANDLE\n    CreateFileW.argtypes = [LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE]\n    CreateFile = CreateFileW # alias\n\nclass _OVERLAPPED(Structure):\n    pass\nOVERLAPPED = _OVERLAPPED\n\nclass _COMSTAT(Structure):\n    pass\nCOMSTAT = _COMSTAT\n\nclass _DCB(Structure):\n    pass\nDCB = _DCB\n\nclass _COMMTIMEOUTS(Structure):\n    pass\nCOMMTIMEOUTS = _COMMTIMEOUTS\n\nGetLastError = _stdcall_libraries['kernel32'].GetLastError\nGetLastError.restype = DWORD\nGetLastError.argtypes = []\n\nLPOVERLAPPED = POINTER(_OVERLAPPED)\nLPDWORD = POINTER(DWORD)\n\nGetOverlappedResult = _stdcall_libraries['kernel32'].GetOverlappedResult\nGetOverlappedResult.restype = BOOL\nGetOverlappedResult.argtypes = [HANDLE, LPOVERLAPPED, LPDWORD, BOOL]\n\nResetEvent = _stdcall_libraries['kernel32'].ResetEvent\nResetEvent.restype = BOOL\nResetEvent.argtypes = [HANDLE]\n\nLPCVOID = c_void_p\n\nWriteFile = _stdcall_libraries['kernel32'].WriteFile\nWriteFile.restype = BOOL\nWriteFile.argtypes = [HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED]\n\nLPVOID = c_void_p\n\nReadFile = _stdcall_libraries['kernel32'].ReadFile\nReadFile.restype = BOOL\nReadFile.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED]\n\nCloseHandle = _stdcall_libraries['kernel32'].CloseHandle\nCloseHandle.restype = BOOL\nCloseHandle.argtypes = [HANDLE]\n\nClearCommBreak = _stdcall_libraries['kernel32'].ClearCommBreak\nClearCommBreak.restype = BOOL\nClearCommBreak.argtypes = [HANDLE]\n\nLPCOMSTAT = POINTER(_COMSTAT)\n\nClearCommError = _stdcall_libraries['kernel32'].ClearCommError\nClearCommError.restype = BOOL\nClearCommError.argtypes = [HANDLE, LPDWORD, LPCOMSTAT]\n\nSetupComm = _stdcall_libraries['kernel32'].SetupComm\nSetupComm.restype = BOOL\nSetupComm.argtypes = [HANDLE, DWORD, DWORD]\n\nEscapeCommFunction = _stdcall_libraries['kernel32'].EscapeCommFunction\nEscapeCommFunction.restype = BOOL\nEscapeCommFunction.argtypes = [HANDLE, DWORD]\n\nGetCommModemStatus = _stdcall_libraries['kernel32'].GetCommModemStatus\nGetCommModemStatus.restype = BOOL\nGetCommModemStatus.argtypes = [HANDLE, LPDWORD]\n\nLPDCB = POINTER(_DCB)\n\nGetCommState = _stdcall_libraries['kernel32'].GetCommState\nGetCommState.restype = BOOL\nGetCommState.argtypes = [HANDLE, LPDCB]\n\nLPCOMMTIMEOUTS = POINTER(_COMMTIMEOUTS)\n\nGetCommTimeouts = _stdcall_libraries['kernel32'].GetCommTimeouts\nGetCommTimeouts.restype = BOOL\nGetCommTimeouts.argtypes = [HANDLE, LPCOMMTIMEOUTS]\n\nPurgeComm = _stdcall_libraries['kernel32'].PurgeComm\nPurgeComm.restype = BOOL\nPurgeComm.argtypes = [HANDLE, DWORD]\n\nSetCommBreak = _stdcall_libraries['kernel32'].SetCommBreak\nSetCommBreak.restype = BOOL\nSetCommBreak.argtypes = [HANDLE]\n\nSetCommMask = _stdcall_libraries['kernel32'].SetCommMask\nSetCommMask.restype = BOOL\nSetCommMask.argtypes = [HANDLE, DWORD]\n\nSetCommState = _stdcall_libraries['kernel32'].SetCommState\nSetCommState.restype = BOOL\nSetCommState.argtypes = [HANDLE, LPDCB]\n\nSetCommTimeouts = _stdcall_libraries['kernel32'].SetCommTimeouts\nSetCommTimeouts.restype = BOOL\nSetCommTimeouts.argtypes = [HANDLE, LPCOMMTIMEOUTS]\n\nWaitForSingleObject = _stdcall_libraries['kernel32'].WaitForSingleObject\nWaitForSingleObject.restype = DWORD\nWaitForSingleObject.argtypes = [HANDLE, DWORD]\n\nONESTOPBIT = 0 # Variable c_int\nTWOSTOPBITS = 2 # Variable c_int\nONE5STOPBITS = 1\n\nNOPARITY = 0 # Variable c_int\nODDPARITY = 1 # Variable c_int\nEVENPARITY = 2 # Variable c_int\nMARKPARITY = 3\nSPACEPARITY = 4\n\nRTS_CONTROL_HANDSHAKE = 2 # Variable c_int\nRTS_CONTROL_DISABLE = 0 # Variable c_int\nRTS_CONTROL_ENABLE = 1 # Variable c_int\nRTS_CONTROL_TOGGLE = 3 # Variable c_int\nSETRTS = 3\nCLRRTS = 4\n\nDTR_CONTROL_HANDSHAKE = 2 # Variable c_int\nDTR_CONTROL_DISABLE = 0 # Variable c_int\nDTR_CONTROL_ENABLE = 1 # Variable c_int\nSETDTR = 5\nCLRDTR = 6\n\nMS_DSR_ON = 32 # Variable c_ulong\nEV_RING = 256 # Variable c_int\nEV_PERR = 512 # Variable c_int\nEV_ERR = 128 # Variable c_int\nSETXOFF = 1 # Variable c_int\nEV_RXCHAR = 1 # Variable c_int\nGENERIC_WRITE = 1073741824 # Variable c_long\nPURGE_TXCLEAR = 4 # Variable c_int\nFILE_FLAG_OVERLAPPED = 1073741824 # Variable c_int\nEV_DSR = 16 # Variable c_int\nMAXDWORD = 4294967295L # Variable c_uint\nEV_RLSD = 32 # Variable c_int\nERROR_IO_PENDING = 997 # Variable c_long\nMS_CTS_ON = 16 # Variable c_ulong\nEV_EVENT1 = 2048 # Variable c_int\nEV_RX80FULL = 1024 # Variable c_int\nPURGE_RXABORT = 2 # Variable c_int\nFILE_ATTRIBUTE_NORMAL = 128 # Variable c_int\nPURGE_TXABORT = 1 # Variable c_int\nSETXON = 2 # Variable c_int\nOPEN_EXISTING = 3 # Variable c_int\nMS_RING_ON = 64 # Variable c_ulong\nEV_TXEMPTY = 4 # Variable c_int\nEV_RXFLAG = 2 # Variable c_int\nMS_RLSD_ON = 128 # Variable c_ulong\nGENERIC_READ = 2147483648L # Variable c_ulong\nEV_EVENT2 = 4096 # Variable c_int\nEV_CTS = 8 # Variable c_int\nEV_BREAK = 64 # Variable c_int\nPURGE_RXCLEAR = 8 # Variable c_int\nINFINITE = 0xFFFFFFFFL\n\n\nclass N11_OVERLAPPED4DOLLAR_48E(Union):\n    pass\nclass N11_OVERLAPPED4DOLLAR_484DOLLAR_49E(Structure):\n    pass\nN11_OVERLAPPED4DOLLAR_484DOLLAR_49E._fields_ = [\n    ('Offset', DWORD),\n    ('OffsetHigh', DWORD),\n]\n\nPVOID = c_void_p\n\nN11_OVERLAPPED4DOLLAR_48E._anonymous_ = ['_0']\nN11_OVERLAPPED4DOLLAR_48E._fields_ = [\n    ('_0', N11_OVERLAPPED4DOLLAR_484DOLLAR_49E),\n    ('Pointer', PVOID),\n]\n_OVERLAPPED._anonymous_ = ['_0']\n_OVERLAPPED._fields_ = [\n    ('Internal', ULONG_PTR),\n    ('InternalHigh', ULONG_PTR),\n    ('_0', N11_OVERLAPPED4DOLLAR_48E),\n    ('hEvent', HANDLE),\n]\n_SECURITY_ATTRIBUTES._fields_ = [\n    ('nLength', DWORD),\n    ('lpSecurityDescriptor', LPVOID),\n    ('bInheritHandle', BOOL),\n]\n_COMSTAT._fields_ = [\n    ('fCtsHold', DWORD, 1),\n    ('fDsrHold', DWORD, 1),\n    ('fRlsdHold', DWORD, 1),\n    ('fXoffHold', DWORD, 1),\n    ('fXoffSent', DWORD, 1),\n    ('fEof', DWORD, 1),\n    ('fTxim', DWORD, 1),\n    ('fReserved', DWORD, 25),\n    ('cbInQue', DWORD),\n    ('cbOutQue', DWORD),\n]\n_DCB._fields_ = [\n    ('DCBlength', DWORD),\n    ('BaudRate', DWORD),\n    ('fBinary', DWORD, 1),\n    ('fParity', DWORD, 1),\n    ('fOutxCtsFlow', DWORD, 1),\n    ('fOutxDsrFlow', DWORD, 1),\n    ('fDtrControl', DWORD, 2),\n    ('fDsrSensitivity', DWORD, 1),\n    ('fTXContinueOnXoff', DWORD, 1),\n    ('fOutX', DWORD, 1),\n    ('fInX', DWORD, 1),\n    ('fErrorChar', DWORD, 1),\n    ('fNull', DWORD, 1),\n    ('fRtsControl', DWORD, 2),\n    ('fAbortOnError', DWORD, 1),\n    ('fDummy2', DWORD, 17),\n    ('wReserved', WORD),\n    ('XonLim', WORD),\n    ('XoffLim', WORD),\n    ('ByteSize', BYTE),\n    ('Parity', BYTE),\n    ('StopBits', BYTE),\n    ('XonChar', c_char),\n    ('XoffChar', c_char),\n    ('ErrorChar', c_char),\n    ('EofChar', c_char),\n    ('EvtChar', c_char),\n    ('wReserved1', WORD),\n]\n_COMMTIMEOUTS._fields_ = [\n    ('ReadIntervalTimeout', DWORD),\n    ('ReadTotalTimeoutMultiplier', DWORD),\n    ('ReadTotalTimeoutConstant', DWORD),\n    ('WriteTotalTimeoutMultiplier', DWORD),\n    ('WriteTotalTimeoutConstant', DWORD),\n]\n__all__ = ['GetLastError', 'MS_CTS_ON', 'FILE_ATTRIBUTE_NORMAL',\n           'DTR_CONTROL_ENABLE', '_COMSTAT', 'MS_RLSD_ON',\n           'GetOverlappedResult', 'SETXON', 'PURGE_TXABORT',\n           'PurgeComm', 'N11_OVERLAPPED4DOLLAR_48E', 'EV_RING',\n           'ONESTOPBIT', 'SETXOFF', 'PURGE_RXABORT', 'GetCommState',\n           'RTS_CONTROL_ENABLE', '_DCB', 'CreateEvent',\n           '_COMMTIMEOUTS', '_SECURITY_ATTRIBUTES', 'EV_DSR',\n           'EV_PERR', 'EV_RXFLAG', 'OPEN_EXISTING', 'DCB',\n           'FILE_FLAG_OVERLAPPED', 'EV_CTS', 'SetupComm',\n           'LPOVERLAPPED', 'EV_TXEMPTY', 'ClearCommBreak',\n           'LPSECURITY_ATTRIBUTES', 'SetCommBreak', 'SetCommTimeouts',\n           'COMMTIMEOUTS', 'ODDPARITY', 'EV_RLSD',\n           'GetCommModemStatus', 'EV_EVENT2', 'PURGE_TXCLEAR',\n           'EV_BREAK', 'EVENPARITY', 'LPCVOID', 'COMSTAT', 'ReadFile',\n           'PVOID', '_OVERLAPPED', 'WriteFile', 'GetCommTimeouts',\n           'ResetEvent', 'EV_RXCHAR', 'LPCOMSTAT', 'ClearCommError',\n           'ERROR_IO_PENDING', 'EscapeCommFunction', 'GENERIC_READ',\n           'RTS_CONTROL_HANDSHAKE', 'OVERLAPPED',\n           'DTR_CONTROL_HANDSHAKE', 'PURGE_RXCLEAR', 'GENERIC_WRITE',\n           'LPDCB', 'CreateEventW', 'SetCommMask', 'EV_EVENT1',\n           'SetCommState', 'LPVOID', 'CreateFileW', 'LPDWORD',\n           'EV_RX80FULL', 'TWOSTOPBITS', 'LPCOMMTIMEOUTS', 'MAXDWORD',\n           'MS_DSR_ON', 'MS_RING_ON',\n           'N11_OVERLAPPED4DOLLAR_484DOLLAR_49E', 'EV_ERR',\n           'ULONG_PTR', 'CreateFile', 'NOPARITY', 'CloseHandle']\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/setup.py",
    "content": "# setup.py for pySerial\n#\n# Windows installer:\n#   \"python setup.py bdist_wininst\"\n#\n# Direct install (all systems):\n#   \"python setup.py install\"\n#\n# For Python 3.x use the corresponding Python executable,\n# e.g. \"python3 setup.py ...\"\n\nimport sys\n\nfrom distutils.core import setup\n\nif sys.version_info >= (3, 0):\n    try:\n        from distutils.command.build_py import build_py_2to3 as build_py\n        from distutils.command.build_scripts import build_scripts_2to3 as build_scripts\n    except ImportError:\n        raise ImportError(\"build_py_2to3 not found in distutils - it is required for Python 3.x\")\n    suffix = \"-py3k\"\nelse:\n    from distutils.command.build_py import build_py\n    from distutils.command.build_scripts import build_scripts\n    suffix = \"\"\n\n\nif sys.version < '2.3':\n    # distutils that old can't cope with the \"classifiers\" or \"download_url\"\n    # keywords and True/False constants and basestring are missing\n    raise ValueError(\"Sorry Python versions older than 2.3 are no longer\"\n                     \"supported - check http://pyserial.sf.net for older \"\n                     \"releases or upgrade your Python installation.\")\n\n# importing version does not work with Python 3 as files have not yet been\n# converted.\n#~ import serial\n#~ version = serial.VERSION\n\nimport re, os\nversion = re.search(\n        \"VERSION.*'(.+)'\",\n        open(os.path.join('serial', '__init__.py')).read()).group(1)\n\n\nsetup(\n    name = \"pyserial\" + suffix,\n    description = \"Python Serial Port Extension\",\n    version = version,\n    author = \"Chris Liechti\",\n    author_email = \"cliechti@gmx.net\",\n    url = \"http://pyserial.sourceforge.net/\",\n    packages = ['serial', 'serial.tools', 'serial.urlhandler'],\n    license = \"Python\",\n    long_description = \"Python Serial Port Extension for Win32, Linux, BSD, Jython, IronPython\",\n    classifiers = [\n        'Development Status :: 5 - Production/Stable',\n        'Intended Audience :: Developers',\n        'Intended Audience :: End Users/Desktop',\n        'License :: OSI Approved :: Python Software Foundation License',\n        'Natural Language :: English',\n        'Operating System :: POSIX',\n        'Operating System :: Microsoft :: Windows',\n        #~ 'Operating System :: Microsoft :: Windows :: Windows CE', # could work due to new ctypes impl. someone needs to confirm that\n        'Programming Language :: Python',\n        'Programming Language :: Python :: 2',\n        'Programming Language :: Python :: 2.3',\n        'Programming Language :: Python :: 2.4',\n        'Programming Language :: Python :: 2.5',\n        'Programming Language :: Python :: 2.6',\n        'Programming Language :: Python :: 2.7',\n        'Programming Language :: Python :: 3',\n        'Programming Language :: Python :: 3.0',\n        'Programming Language :: Python :: 3.1',\n        'Programming Language :: Python :: 3.2',\n        'Topic :: Communications',\n        'Topic :: Software Development :: Libraries',\n        'Topic :: Software Development :: Libraries :: Python Modules',\n        'Topic :: Terminals :: Serial',\n    ],\n    platforms = 'any',\n    cmdclass = {'build_py': build_py, 'build_scripts': build_scripts},\n\n    scripts = ['serial/tools/miniterm.py'],\n)\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/test/run_all_tests.py",
    "content": "#! /usr/bin/env python\n\n\"\"\"\\\nUnitTest runner. This one searches for all files named test_*.py and collects\nall test cases from these files. Finally it runs all tests and prints a\nsummary.\n\"\"\"\n\nimport unittest\nimport sys\nimport os\nimport time\n\n# inject local copy to avoid testing the installed version instead of the\n# working copy\nsys.path.insert(0, '..')\n\nimport serial\nprint \"Patching sys.path to test local version. Testing Version: %s\" % (serial.VERSION,)\n\nPORT = 'loop://'\nif len(sys.argv) > 1:\n    PORT = sys.argv[1]\n\n# find files and the tests in them\nmainsuite = unittest.TestSuite()\nfor modulename in [os.path.splitext(x)[0]\n    for x in os.listdir('.')\n        if x != __file__ and x.startswith(\"test\") and x.endswith(\".py\")\n]:\n    try:\n        module = __import__(modulename)\n    except ImportError:\n        print \"skipping %s\" % modulename\n    else:\n        module.PORT = PORT\n        testsuite = unittest.findTestCases(module)\n        print \"found %s tests in %r\" % (testsuite.countTestCases(), modulename)\n        mainsuite.addTest(testsuite)\n\nverbosity = 1\nif '-v' in sys.argv[1:]:\n    verbosity = 2\n\n# run the collected tests\ntestRunner = unittest.TextTestRunner(verbosity=verbosity)\n#~ testRunner = unittest.ConsoleTestRunner(verbosity=verbosity)\nresult = testRunner.run(mainsuite)\n\n# set exit code accordingly to test results\nsys.exit(not result.wasSuccessful())\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/test/test.py",
    "content": "#! /usr/bin/env python\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# see __init__.py\n#\n# (C) 2001-2008 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n\n\"\"\"\\\nSome tests for the serial module.\nPart of pyserial (http://pyserial.sf.net)  (C)2001-2009 cliechti@gmx.net\n\nIntended to be run on different platforms, to ensure portability of\nthe code.\n\nFor all these tests a simple hardware is required.\nLoopback HW adapter:\nShortcut these pin pairs:\n TX  <-> RX\n RTS <-> CTS\n DTR <-> DSR\n\nOn a 9 pole DSUB these are the pins (2-3) (4-6) (7-8)\n\"\"\"\n\nimport unittest\nimport threading\nimport time\nimport sys\nimport serial\n\n# on which port should the tests be performed:\nPORT = 0\n\nif sys.version_info >= (3, 0):\n    def data(string):\n        return bytes(string, 'latin1')\n    bytes_0to255 = bytes(range(256))\nelse:\n    def data(string): return string\n    bytes_0to255 = ''.join([chr(x) for x in range(256)])\n\n\ndef segments(data, size=16):\n    for a in range(0, len(data), size):\n        yield data[a:a+size]\n\n\nclass Test4_Nonblocking(unittest.TestCase):\n    \"\"\"Test with timeouts\"\"\"\n    timeout = 0\n\n    def setUp(self):\n        self.s = serial.serial_for_url(PORT, timeout=self.timeout)\n\n    def tearDown(self):\n        self.s.close()\n\n    def test0_Messy(self):\n        \"\"\"NonBlocking (timeout=0)\"\"\"\n        # this is only here to write out the message in verbose mode\n        # because Test3 and Test4 print the same messages\n\n    def test1_ReadEmpty(self):\n        \"\"\"timeout: After port open, the input buffer must be empty\"\"\"\n        self.failUnlessEqual(self.s.read(1), data(''), \"expected empty buffer\")\n\n    def test2_Loopback(self):\n        \"\"\"timeout: each sent character should return (binary test).\n           this is also a test for the binary capability of a port.\"\"\"\n        for block in segments(bytes_0to255):\n            length = len(block)\n            self.s.write(block)\n            # there might be a small delay until the character is ready (especially on win32)\n            time.sleep(0.05)\n            self.failUnlessEqual(self.s.inWaiting(), length, \"expected exactly %d character for inWainting()\" % length)\n            self.failUnlessEqual(self.s.read(length), block)#, \"expected a %r which was written before\" % block)\n        self.failUnlessEqual(self.s.read(1), data(''), \"expected empty buffer after all sent chars are read\")\n\n    def test2_LoopbackTimeout(self):\n        \"\"\"timeout: test the timeout/immediate return.\n        partial results should be returned.\"\"\"\n        self.s.write(data(\"HELLO\"))\n        time.sleep(0.1)    # there might be a small delay until the character is ready (especially on win32 and rfc2217)\n        # read more characters as are available to run in the timeout\n        self.failUnlessEqual(self.s.read(10), data('HELLO'), \"expected the 'HELLO' which was written before\")\n        self.failUnlessEqual(self.s.read(1), data(''), \"expected empty buffer after all sent chars are read\")\n\n\nclass Test3_Timeout(Test4_Nonblocking):\n    \"\"\"Same tests as the NonBlocking ones but this time with timeout\"\"\"\n    timeout = 1\n\n    def test0_Messy(self):\n        \"\"\"Blocking (timeout=1)\"\"\"\n        # this is only here to write out the message in verbose mode\n        # because Test3 and Test4 print the same messages\n\n\nclass SendEvent(threading.Thread):\n    def __init__(self, serial, delay=3):\n        threading.Thread.__init__(self)\n        self.serial = serial\n        self.delay = delay\n        self.x = threading.Event()\n        self.stopped = 0\n        self.start()\n\n    def run(self):\n        time.sleep(self.delay)\n        self.x.set()\n        if not self.stopped:\n            self.serial.write(data(\"E\"))\n            self.serial.flush()\n\n    def isSet(self):\n        return self.x.isSet()\n\n    def stop(self):\n        self.stopped = 1\n        self.x.wait()\n\nclass Test1_Forever(unittest.TestCase):\n    \"\"\"Tests a port with no timeout. These tests require that a\n    character is sent after some time to stop the test, this is done\n    through the SendEvent class and the Loopback HW.\"\"\"\n    def setUp(self):\n        self.s = serial.serial_for_url(PORT, timeout=None)\n        self.event = SendEvent(self.s)\n\n    def tearDown(self):\n        self.event.stop()\n        self.s.close()\n\n    def test2_ReadEmpty(self):\n        \"\"\"no timeout: after port open, the input buffer must be empty (read).\n        a character is sent after some time to terminate the test (SendEvent).\"\"\"\n        c = self.s.read(1)\n        if not (self.event.isSet() and c == data('E')):\n            self.fail(\"expected marker (evt=%r, c=%r)\" % (self.event.isSet(), c))\n\n\nclass Test2_Forever(unittest.TestCase):\n    \"\"\"Tests a port with no timeout\"\"\"\n    def setUp(self):\n        self.s = serial.serial_for_url(PORT, timeout=None)\n\n    def tearDown(self):\n        self.s.close()\n\n    def test1_inWaitingEmpty(self):\n        \"\"\"no timeout: after port open, the input buffer must be empty (inWaiting)\"\"\"\n        self.failUnlessEqual(self.s.inWaiting(), 0, \"expected empty buffer\")\n\n    def test2_Loopback(self):\n        \"\"\"no timeout: each sent character should return (binary test).\n           this is also a test for the binary capability of a port.\"\"\"\n        for block in segments(bytes_0to255):\n            length = len(block)\n            self.s.write(block)\n            # there might be a small delay until the character is ready (especially on win32 and rfc2217)\n            time.sleep(0.05)\n            self.failUnlessEqual(self.s.inWaiting(), length)#, \"expected exactly %d character for inWainting()\" % length)\n            self.failUnlessEqual(self.s.read(length), block) #, \"expected %r which was written before\" % block)\n        self.failUnlessEqual(self.s.inWaiting(), 0, \"expected empty buffer after all sent chars are read\")\n\n\nclass Test0_DataWires(unittest.TestCase):\n    \"\"\"Test modem control lines\"\"\"\n    def setUp(self):\n        self.s = serial.serial_for_url(PORT)\n\n    def tearDown(self):\n        self.s.close()\n\n    def test1_RTS(self):\n        \"\"\"Test RTS/CTS\"\"\"\n        self.s.setRTS(0)\n        time.sleep(1.1)\n        self.failUnless(not self.s.getCTS(), \"CTS -> 0\")\n        self.s.setRTS(1)\n        time.sleep(1.1)\n        self.failUnless(self.s.getCTS(), \"CTS -> 1\")\n\n    def test2_DTR(self):\n        \"\"\"Test DTR/DSR\"\"\"\n        self.s.setDTR(0)\n        time.sleep(1.1)\n        self.failUnless(not self.s.getDSR(), \"DSR -> 0\")\n        self.s.setDTR(1)\n        time.sleep(1.1)\n        self.failUnless(self.s.getDSR(), \"DSR -> 1\")\n\n    def test3_RI(self):\n        \"\"\"Test RI\"\"\"\n        self.failUnless(not self.s.getRI(), \"RI -> 0\")\n\n\nclass Test_MoreTimeouts(unittest.TestCase):\n    \"\"\"Test with timeouts\"\"\"\n    def setUp(self):\n        # create an closed serial port\n        self.s = serial.serial_for_url(PORT, do_not_open=True)\n\n    def tearDown(self):\n        self.s.close()\n\n    def test_WriteTimeout(self):\n        \"\"\"Test write() timeout.\"\"\"\n        # use xonxoff setting and the loop-back adapter to switch traffic on hold\n        self.s.port = PORT\n        self.s.writeTimeout = 1\n        self.s.xonxoff = 1\n        self.s.open()\n        self.s.write(serial.XOFF)\n        time.sleep(0.5) # some systems need a little delay so that they can react on XOFF\n        t1 = time.time()\n        self.failUnlessRaises(serial.SerialTimeoutException, self.s.write, data(\"timeout please\"*200))\n        t2 = time.time()\n        self.failUnless( 0.9 <= (t2-t1) < 2.1, \"Timeout not in the given interval (%s)\" % (t2-t1))\n\n\nif __name__ == '__main__':\n    import sys\n    sys.stdout.write(__doc__)\n    if len(sys.argv) > 1:\n        PORT = sys.argv[1]\n    sys.stdout.write(\"Testing port: %r\\n\" % PORT)\n    sys.argv[1:] = ['-v']\n    # When this module is executed from the command-line, it runs all its tests\n    unittest.main()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/test/test_advanced.py",
    "content": "#!/usr/bin/env python\n# needs at least python 2.2.3\n\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# see __init__.py\n#\n# (C) 2001-2003 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n\n\"\"\"\\\nSome tests for the serial module.\nPart of pyserial (http://pyserial.sf.net)  (C)2002 cliechti@gmx.net\n\nIntended to be run on different platforms, to ensure portability of\nthe code.\n\nThese tests open a serial port and change all the settings on the fly.\nIf the port is really correctly configured cannot be determined - that\nwould require external hardware or a null modem cable and an other\nserial port library... Thus it mainly tests that all features are\ncorrectly implemented and that the interface does what it should.\n\n\"\"\"\n\nimport unittest\nimport serial\n\n# on which port should the tests be performed:\nPORT = 0\n\nclass Test_ChangeAttributes(unittest.TestCase):\n    \"\"\"Test with timeouts\"\"\"\n\n    def setUp(self):\n        # create a closed serial port\n        self.s = serial.serial_for_url(PORT, do_not_open=True)\n\n    def tearDown(self):\n        self.s.close()\n\n    def test_PortSetting(self):\n        self.s.port = PORT\n        # portstr has to be set\n        if isinstance(PORT, str):\n            self.failUnlessEqual(self.s.portstr.lower(), PORT.lower())\n        else:\n            self.failUnlessEqual(self.s.portstr, serial.device(PORT))\n        # test internals\n        self.failUnlessEqual(self.s._port, PORT)\n        # test on the fly change\n        self.s.open()\n        self.failUnless(self.s.isOpen())\n        try:\n            self.s.port = 0\n        except serial.SerialException: # port not available on system\n            pass        # can't test on this machine...\n        else:\n            self.failUnless(self.s.isOpen())\n            self.failUnlessEqual(self.s.port, 0)\n            self.failUnlessEqual(self.s.portstr, serial.device(0))\n        try:\n            self.s.port = 1\n        except serial.SerialException: # port not available on system\n            pass        # can't test on this machine...\n        else:\n            self.failUnless(self.s.isOpen())\n            self.failUnlessEqual(self.s.port, 1)\n            self.failUnlessEqual(self.s.portstr, serial.device(1))\n\n    def test_DoubleOpen(self):\n        self.s.port = PORT\n        self.s.open()\n        # calling open for a second time is an error\n        self.failUnlessRaises(serial.SerialException, self.s.open)\n\n\n    def test_BaudrateSetting(self):\n        self.s.port = PORT\n        self.s.open()\n        for baudrate in (300, 9600, 19200, 115200):\n            self.s.baudrate = baudrate\n            # test get method\n            self.failUnlessEqual(self.s.baudrate, baudrate)\n            # test internals\n            self.failUnlessEqual(self.s._baudrate, baudrate)\n        # test illegal values\n        for illegal_value in (-300, -1, 'a', None):\n            self.failUnlessRaises(ValueError, self.s.setBaudrate, illegal_value)\n\n    # skip this test as pyserial now tries to set even non standard baud rates.\n    # therefore the test can not choose a value that fails on any system.\n    def disabled_test_BaudrateSetting2(self):\n        # test illegal values, depending on machine/port some of these may be valid...\n        self.s.port = PORT\n        self.s.open()\n        for illegal_value in (500000, 576000, 921600, 92160):\n            self.failUnlessRaises(ValueError, self.s.setBaudrate, illegal_value)\n\n    def test_BytesizeSetting(self):\n        for bytesize in (5,6,7,8):\n            self.s.bytesize = bytesize\n            # test get method\n            self.failUnlessEqual(self.s.bytesize, bytesize)\n            # test internals\n            self.failUnlessEqual(self.s._bytesize, bytesize)\n        # test illegal values\n        for illegal_value in (0, 1, 3, 4, 9, 10, 'a', None):\n            self.failUnlessRaises(ValueError, self.s.setByteSize, illegal_value)\n\n    def test_ParitySetting(self):\n        for parity in (serial.PARITY_NONE, serial.PARITY_EVEN, serial.PARITY_ODD):\n            self.s.parity = parity\n            # test get method\n            self.failUnlessEqual(self.s.parity, parity)\n            # test internals\n            self.failUnlessEqual(self.s._parity, parity)\n        # test illegal values\n        for illegal_value in (0, 57, 'a', None):\n            self.failUnlessRaises(ValueError, self.s.setParity, illegal_value)\n\n    def test_StopbitsSetting(self):\n        for stopbits in (1, 2):\n            self.s.stopbits = stopbits\n            # test get method\n            self.failUnlessEqual(self.s.stopbits, stopbits)\n            # test internals\n            self.failUnlessEqual(self.s._stopbits, stopbits)\n        # test illegal values\n        for illegal_value in (0, 3, 2.5, 57, 'a', None):\n            self.failUnlessRaises(ValueError, self.s.setStopbits, illegal_value)\n\n    def test_TimeoutSetting(self):\n        for timeout in (None, 0, 1, 3.14159, 10, 1000, 3600):\n            self.s.timeout = timeout\n            # test get method\n            self.failUnlessEqual(self.s.timeout, timeout)\n            # test internals\n            self.failUnlessEqual(self.s._timeout, timeout)\n        # test illegal values\n        for illegal_value in (-1, 'a'):\n            self.failUnlessRaises(ValueError, self.s.setTimeout, illegal_value)\n\n    def test_XonXoffSetting(self):\n        for xonxoff in (True, False):\n            self.s.xonxoff = xonxoff\n            # test get method\n            self.failUnlessEqual(self.s.xonxoff, xonxoff)\n            # test internals\n            self.failUnlessEqual(self.s._xonxoff, xonxoff)\n        # no illegal values here, normal rules for the boolean value of an\n        # object are used thus all objects have a truth value.\n\n    def test_RtsCtsSetting(self):\n        for rtscts in (True, False):\n            self.s.rtscts = rtscts\n            # test get method\n            self.failUnlessEqual(self.s.rtscts, rtscts)\n            # test internals\n            self.failUnlessEqual(self.s._rtscts, rtscts)\n        # no illegal values here, normal rules for the boolean value of an\n        # object are used thus all objects have a truth value.\n\n    # this test does not work anymore since serial_for_url that is used\n    # now, already sets a port\n    def disabled_test_UnconfiguredPort(self):\n        # an unconfigured port cannot be opened\n        self.failUnlessRaises(serial.SerialException, self.s.open)\n\n    def test_PortOpenClose(self):\n        self.s.port = PORT\n        for i in range(3):\n            # open the port and check flag\n            self.failUnless(not self.s.isOpen())\n            self.s.open()\n            self.failUnless(self.s.isOpen())\n            self.s.close()\n            self.failUnless(not self.s.isOpen())\n\n\nif __name__ == '__main__':\n    import sys\n    sys.stdout.write(__doc__)\n    if len(sys.argv) > 1:\n        PORT = sys.argv[1]\n    sys.stdout.write(\"Testing port: %r\\n\" % PORT)\n    sys.argv[1:] = ['-v']\n    # When this module is executed from the command-line, it runs all its tests\n    unittest.main()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/test/test_high_load.py",
    "content": "#!/usr/bin/env python\n#Python Serial Port Extension for Win32, Linux, BSD, Jython\n#see __init__.py\n#\n#(C) 2001-2003 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n\n\"\"\"Some tests for the serial module.\nPart of pyserial (http://pyserial.sf.net)  (C)2002-2003 cliechti@gmx.net\n\nIntended to be run on different platforms, to ensure portability of\nthe code.\n\nFor all these tests a simple hardware is required.\nLoopback HW adapter:\nShortcut these pin pairs:\n TX  <-> RX\n RTS <-> CTS\n DTR <-> DSR\n\nOn a 9 pole DSUB these are the pins (2-3) (4-6) (7-8)\n\"\"\"\n\nimport unittest\nimport sys\nimport serial\n\n# on which port should the tests be performed:\nPORT = 0\nBAUDRATE = 115200\n#~ BAUDRATE=9600\n\nif sys.version_info >= (3, 0):\n    bytes_0to255 = bytes(range(256))\nelse:\n    bytes_0to255 = ''.join([chr(x) for x in range(256)])\n\n\nclass TestHighLoad(unittest.TestCase):\n    \"\"\"Test sending and receiving large amount of data\"\"\"\n\n    N = 16\n    #~ N = 1\n\n    def setUp(self):\n        self.s = serial.serial_for_url(PORT, BAUDRATE, timeout=10)\n\n    def tearDown(self):\n        self.s.close()\n\n    def test0_WriteReadLoopback(self):\n        \"\"\"Send big strings, write/read order.\"\"\"\n        for i in range(self.N):\n            q = bytes_0to255\n            self.s.write(q)\n            self.failUnlessEqual(self.s.read(len(q)), q) # expected same which was written before\n        self.failUnlessEqual(self.s.inWaiting(), 0) # expected empty buffer after all sent chars are read\n\n    def test1_WriteWriteReadLoopback(self):\n        \"\"\"Send big strings, multiple write one read.\"\"\"\n        q = bytes_0to255\n        for i in range(self.N):\n            self.s.write(q)\n        read = self.s.read(len(q)*self.N)\n        self.failUnlessEqual(read, q*self.N, \"expected what was written before. got %d bytes, expected %d\" % (len(read), self.N*len(q)))\n        self.failUnlessEqual(self.s.inWaiting(), 0) # \"expected empty buffer after all sent chars are read\")\n\n\nif __name__ == '__main__':\n    import sys\n    sys.stdout.write(__doc__)\n    if len(sys.argv) > 1:\n        PORT = sys.argv[1]\n    sys.stdout.write(\"Testing port: %r\\n\" % PORT)\n    sys.argv[1:] = ['-v']\n    # When this module is executed from the command-line, it runs all its tests\n    unittest.main()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/test/test_iolib.py",
    "content": "#! /usr/bin/env python\n#\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# see __init__.py\n#\n# (C) 2001-2009 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n\n\"\"\"\\\nSome tests for the serial module.\nPart of pyserial (http://pyserial.sf.net)  (C)2001-2009 cliechti@gmx.net\n\nIntended to be run on different platforms, to ensure portability of\nthe code.\n\nThis modules contains test for the interaction between Serial and the io\nlibrary. This only works on Python 2.6+ that introduced the io library.\n\nFor all these tests a simple hardware is required.\nLoopback HW adapter:\nShortcut these pin pairs:\n TX  <-> RX\n RTS <-> CTS\n DTR <-> DSR\n\nOn a 9 pole DSUB these are the pins (2-3) (4-6) (7-8)\n\"\"\"\n\nimport unittest\nimport sys\n\nif __name__ == '__main__'  and sys.version_info < (2, 6):\n    sys.stderr.write(\"\"\"\\\n==============================================================================\nWARNING: this test is intended for Python 2.6 and newer where the io library\nis available. This seems to be an older version of Python running.\nContinuing anyway...\n==============================================================================\n\"\"\")\n\nimport io\nimport serial\n\n# trick to make that this test run under 2.6 and 3.x without modification.\n# problem is, io library on 2.6 does NOT accept type 'str' and 3.x doesn't\n# like u'nicode' strings with the prefix and it is not providing an unicode\n# function ('str' is now what 'unicode' used to be)\nif sys.version_info >= (3, 0):\n    def unicode(x): return x\n\n\n# on which port should the tests be performed:\nPORT = 0\n\nclass Test_SerialAndIO(unittest.TestCase):\n\n    def setUp(self):\n        self.s = serial.serial_for_url(PORT, timeout=1)\n        self.io = io.TextIOWrapper(io.BufferedRWPair(self.s, self.s))\n\n    def tearDown(self):\n        self.s.close()\n\n    def test_hello_raw(self):\n        self.io.write(unicode(\"hello\\n\"))\n        self.io.flush() # it is buffering. required to get the data out\n        hello = self.io.readline()\n        self.failUnlessEqual(hello, unicode(\"hello\\n\"))\n\n\nif __name__ == '__main__':\n    import sys\n    sys.stdout.write(__doc__)\n    if len(sys.argv) > 1:\n        PORT = sys.argv[1]\n    sys.stdout.write(\"Testing port: %r\\n\" % PORT)\n    sys.argv[1:] = ['-v']\n    # When this module is executed from the command-line, it runs all its tests\n    unittest.main()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/test/test_readline.py",
    "content": "#! /usr/bin/env python\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# see __init__.py\n#\n# (C) 2010 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n\n\"\"\"\\\nSome tests for the serial module.\nPart of pyserial (http://pyserial.sf.net)  (C)2010 cliechti@gmx.net\n\nIntended to be run on different platforms, to ensure portability of\nthe code.\n\nFor all these tests a simple hardware is required.\nLoopback HW adapter:\nShortcut these pin pairs:\n TX  <-> RX\n RTS <-> CTS\n DTR <-> DSR\n\nOn a 9 pole DSUB these are the pins (2-3) (4-6) (7-8)\n\"\"\"\n\nimport unittest\nimport threading\nimport time\nimport sys\nimport serial\n\n#~ print serial.VERSION\n\n# on which port should the tests be performed:\nPORT = 0\n\nif sys.version_info >= (3, 0):\n    def data(string):\n        return bytes(string, 'latin1')\nelse:\n    def data(string): return string\n\n\n\nclass Test_Readline(unittest.TestCase):\n    \"\"\"Test readline function\"\"\"\n\n    def setUp(self):\n        self.s = serial.serial_for_url(PORT, timeout=1)\n\n    def tearDown(self):\n        self.s.close()\n\n    def test_readline(self):\n        \"\"\"Test readline method\"\"\"\n        self.s.write(serial.to_bytes(\"1\\n2\\n3\\n\"))\n        self.failUnlessEqual(self.s.readline(), serial.to_bytes(\"1\\n\"))\n        self.failUnlessEqual(self.s.readline(), serial.to_bytes(\"2\\n\"))\n        self.failUnlessEqual(self.s.readline(), serial.to_bytes(\"3\\n\"))\n        # this time we will get a timeout\n        self.failUnlessEqual(self.s.readline(), serial.to_bytes(\"\"))\n\n    def test_readlines(self):\n        \"\"\"Test readlines method\"\"\"\n        self.s.write(serial.to_bytes(\"1\\n2\\n3\\n\"))\n        self.failUnlessEqual(\n                self.s.readlines(),\n                [serial.to_bytes(\"1\\n\"), serial.to_bytes(\"2\\n\"), serial.to_bytes(\"3\\n\")]\n                )\n\n    def test_xreadlines(self):\n        \"\"\"Test xreadlines method (skipped for io based systems)\"\"\"\n        if hasattr(self.s, 'xreadlines'):\n            self.s.write(serial.to_bytes(\"1\\n2\\n3\\n\"))\n            self.failUnlessEqual(\n                    list(self.s.xreadlines()),\n                    [serial.to_bytes(\"1\\n\"), serial.to_bytes(\"2\\n\"), serial.to_bytes(\"3\\n\")]\n                    )\n\n    def test_for_in(self):\n        \"\"\"Test for line in s\"\"\"\n        self.s.write(serial.to_bytes(\"1\\n2\\n3\\n\"))\n        lines = []\n        for line in self.s:\n            lines.append(line)\n        self.failUnlessEqual(\n                lines,\n                [serial.to_bytes(\"1\\n\"), serial.to_bytes(\"2\\n\"), serial.to_bytes(\"3\\n\")]\n                )\n\n    def test_alternate_eol(self):\n        \"\"\"Test readline with alternative eol settings (skipped for io based systems)\"\"\"\n        if hasattr(self.s, 'xreadlines'): # test if it is our FileLike base class\n            self.s.write(serial.to_bytes(\"no\\rno\\nyes\\r\\n\"))\n            self.failUnlessEqual(\n                    self.s.readline(eol=serial.to_bytes(\"\\r\\n\")),\n                    serial.to_bytes(\"no\\rno\\nyes\\r\\n\"))\n\n\nif __name__ == '__main__':\n    import sys\n    sys.stdout.write(__doc__)\n    if len(sys.argv) > 1:\n        PORT = sys.argv[1]\n    sys.stdout.write(\"Testing port: %r\\n\" % PORT)\n    sys.argv[1:] = ['-v']\n    # When this module is executed from the command-line, it runs all its tests\n    unittest.main()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/pyserial-2.6/test/test_url.py",
    "content": "#! /usr/bin/env python\n# Python Serial Port Extension for Win32, Linux, BSD, Jython\n# see __init__.py\n#\n# (C) 2001-2008 Chris Liechti <cliechti@gmx.net>\n# this is distributed under a free software license, see license.txt\n\n\"\"\"\\\nSome tests for the serial module.\nPart of pySerial (http://pyserial.sf.net)  (C)2001-2011 cliechti@gmx.net\n\nIntended to be run on different platforms, to ensure portability of\nthe code.\n\nCover some of the aspects of serial_for_url and the extension mechanism.\n\"\"\"\n\nimport unittest\nimport time\nimport sys\nimport serial\n\n\nclass Test_URL(unittest.TestCase):\n    \"\"\"Test serial_for_url\"\"\"\n\n    def test_loop(self):\n        \"\"\"loop interface\"\"\"\n        s = serial.serial_for_url('loop://', do_not_open=True)\n\n    def test_bad_url(self):\n        \"\"\"invalid protocol specified\"\"\"\n        self.failUnlessRaises(ValueError, serial.serial_for_url, \"imnotknown://\")\n\n    def test_custom_url(self):\n        \"\"\"custom protocol handlers\"\"\"\n        # it's unknown\n        self.failUnlessRaises(ValueError, serial.serial_for_url, \"test://\")\n        # add search path\n        serial.protocol_handler_packages.append('handlers')\n        # now it should work\n        s = serial.serial_for_url(\"test://\")\n        # remove our handler again\n        serial.protocol_handler_packages.remove('handlers')\n        # so it should not work anymore\n        self.failUnlessRaises(ValueError, serial.serial_for_url, \"test://\")\n\n\nif __name__ == '__main__':\n    import sys\n    sys.stdout.write(__doc__)\n    sys.argv[1:] = ['-v']\n    # When this module is executed from the command-line, it runs all its tests\n    unittest.main()\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/jsonrpc/__init__.py",
    "content": "\n\"\"\"\n  Copyright (c) 2007 Jan-Klaas Kollhof\n\n  This file is part of jsonrpc.\n\n  jsonrpc is free software; you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation; either version 2.1 of the License, or\n  (at your option) any later version.\n\n  This software is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public License\n  along with this software; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\"\"\"\n\nfrom jsonrpc.json import loads, dumps, JSONEncodeException, JSONDecodeException\nfrom jsonrpc.proxy import ServiceProxy, JSONRPCException\nfrom jsonrpc.serviceHandler import ServiceMethod, ServiceHandler, ServiceMethodNotFound, ServiceException\nfrom jsonrpc.cgiwrapper import handleCGI\nfrom jsonrpc.modpywrapper import handler"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/jsonrpc/_tests/__init__.py",
    "content": "\n\"\"\"\n  Copyright (c) 2007 Jan-Klaas Kollhof\n\n  This file is part of jsonrpc.\n\n  jsonrpc is free software; you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation; either version 2.1 of the License, or\n  (at your option) any later version.\n\n  This software is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public License\n  along with this software; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\"\"\"\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/jsonrpc/_tests/test_cgiwrapper.py",
    "content": "\n\"\"\"\n  Copyright (c) 2007 Jan-Klaas Kollhof\n\n  This file is part of jsonrpc.\n\n  jsonrpc is free software; you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation; either version 2.1 of the License, or\n  (at your option) any later version.\n\n  This software is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public License\n  along with this software; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\"\"\"\nimport unittest\nimport jsonrpc\nfrom types import *\n\nclass Service(object):\n    @jsonrpc.ServiceMethod\n    def echo(self, arg):\n        return arg\n\n\nclass  TestCGIWrapper(unittest.TestCase):\n\n    def setUp(self):\n        pass\n\n    def tearDown(self):\n        pass\n\n    def test_runCGIHandler(self):\n        from StringIO import StringIO\n\n        json=u'{\"method\":\"echo\",\"params\":[\"foobar\"], \"id\":\"\"}'\n        fin=StringIO(json)\n        fout=StringIO()\n        \n        env = {\"CONTENT_LENGTH\":len(json)}\n\n        jsonrpc.handleCGI(service=Service(), fin=fin, fout=fout, env=env)\n\n        data = StringIO(fout.getvalue())\n        data.readline()\n        data.readline()\n        data = data.read()\n        self.assertEquals(jsonrpc.loads(data), {\"result\":\"foobar\", \"error\":None, \"id\":\"\"})\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/jsonrpc/_tests/test_json.py",
    "content": "\n\"\"\"\n  Copyright (c) 2007 Jan-Klaas Kollhof\n\n  This file is part of jsonrpc.\n\n  jsonrpc is free software; you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation; either version 2.1 of the License, or\n  (at your option) any later version.\n\n  This software is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public License\n  along with this software; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\"\"\"\n\nimport unittest\nimport jsonrpc\nfrom types import *\n\n\n\nclass  TestDumps(unittest.TestCase):\n    def setUp(self):\n        pass\n\n    def tearDown(self):\n        pass\n\n    \n    def assertJSON(self, json, expectedJSON):\n        self.assert_(type(json) is UnicodeType)\n        self.assertEqual(json, expectedJSON)\n           \n    def test_Number(self):\n        json = jsonrpc.dumps(1)\n        self.assertJSON(json, u'1')\n        \n        json = jsonrpc.dumps(0xffffffffffffffffffffffff)\n        self.assertJSON(json, u'79228162514264337593543950335')\n\n    def test_None(self):\n        json = jsonrpc.dumps(None)\n        self.assertJSON(json, u'null')\n        \n    def test_Boolean(self):\n        json = jsonrpc.dumps(False)\n        self.assertJSON(json, u'false')\n        json = jsonrpc.dumps(True)\n        self.assertJSON(json, u'true')\n\n    def test_Float(self):\n        json = jsonrpc.dumps(1.2345)\n        self.assertJSON(json, u'1.2345')\n\n        json =jsonrpc.dumps(1.2345e67)\n        self.assertJSON(json, u'1.2345e+67')\n\n        json =jsonrpc.dumps(1.2345e-67)\n        self.assertJSON(json, u'1.2345e-67')\n\n    def test_String(self):\n        json = jsonrpc.dumps('foobar')\n        self.assertJSON(json, u'\"foobar\"')\n\n        json = jsonrpc.dumps('foobar')\n        self.assertJSON(json, u'\"foobar\"')\n\n    def test_StringEscapedChars(self):\n        json = jsonrpc.dumps('\\n \\f \\t \\b \\r \\\\ \" /')\n        self.assertJSON(json, u'\"\\\\n \\\\f \\\\t \\\\b \\\\r \\\\\\\\ \\\\\" \\\\/\"')\n\n    def test_StringEscapedUnicodeChars(self):\n        json = jsonrpc.dumps(u'\\0 \\x19 \\x20\\u0130')\n        self.assertJSON(json, u'\"\\\\u0000 \\\\u0019  \\u0130\"')\n\n    def test_Array(self):\n        json = jsonrpc.dumps([1, 2.3e45, 'foobar'])\n        self.assertJSON(json, u'[1,2.3e+45,\"foobar\"]')\n\n    def test_Dictionary(self):\n        json = jsonrpc.dumps({'foobar':'spam', 'a':[1,2,3]})\n        self.assertJSON(json, u'{\"a\":[1,2,3],\"foobar\":\"spam\"}')\n\n    def test_FailOther(self):\n        self.failUnlessRaises(jsonrpc.JSONEncodeException, lambda:jsonrpc.dumps(self))\n\n        \n        \n\nclass  TestLoads(unittest.TestCase):\n    def setUp(self):\n        pass\n\n    def tearDown(self):\n        pass\n\n\n    def test_String(self):\n\n        json = jsonrpc.dumps(\"foobar\")\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, u\"foobar\")\n    \n    def test_StringEscapedChars(self):\n        json = '\"\\\\n \\\\t \\\\r \\\\b \\\\f \\\\\\\\ \\\\/ /\"'\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, u'\\n \\t \\r \\b \\f \\\\ / /')\n        \n    def test_StringEscapedUnicodeChars(self):\n        json = jsonrpc.dumps(u'\\u0000 \\u0019')\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, u'\\0 \\x19')\n        \n    def test_Array(self):\n        json = jsonrpc.dumps(['1', ['2','3']])\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, ['1', ['2','3']])\n\n    def test_Dictionary(self):\n        json = jsonrpc.dumps({'foobar':'spam', 'nested':{'a':'b'}})\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, {'foobar':'spam', 'nested':{'a':'b'}})\n\n\n    def test_Int(self):\n        json = jsonrpc.dumps(1234)\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, 1234)\n\n\n    def test_NegativeInt(self):\n        json = jsonrpc.dumps(-1234)\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, -1234)\n\n    def test_NumberAtEndOfArray(self):\n        json = jsonrpc.dumps([-1234])\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, [-1234])\n\n    def test_StrAtEndOfArray(self):\n        json = jsonrpc.dumps(['foobar'])\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, ['foobar'])\n            \n    def test_Float(self):\n        json = jsonrpc.dumps(1234.567)\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, 1234.567)\n\n    def test_Exponential(self):\n        json = jsonrpc.dumps(1234.567e89)\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, 1234.567e89)\n\n    def test_True(self):\n        json = jsonrpc.dumps(True)\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, True)\n\n    def test_False(self):\n        json = jsonrpc.dumps(False)\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, False)\n\n    def test_None(self):\n        json = jsonrpc.dumps(None)\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, None)\n\n    def test_NestedDictAllTypes(self):\n        json = jsonrpc.dumps({'s':'foobar', 'int':1234, 'float':1234.567, 'exp':1234.56e78,\n                                            'negInt':-1234, 'None':None,'True':True, 'False':False,\n                                            'list':[1,2,4,{}], 'dict':{'a':'b'}})\n        obj = jsonrpc.loads(json)\n        self.assertEquals(obj, {'s':'foobar', 'int':1234, 'float':1234.567, 'exp':1234.56e78,\n                                            'negInt':-1234, 'None':None,'True':True, 'False':False,\n                                            'list':[1,2,4,{}], 'dict':{'a':'b'}})\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/jsonrpc/_tests/test_modpywrapper.py",
    "content": "\n\"\"\"\n  Copyright (c) 2007 Jan-Klaas Kollhof\n\n  This file is part of jsonrpc.\n\n  jsonrpc is free software; you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation; either version 2.1 of the License, or\n  (at your option) any later version.\n\n  This software is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public License\n  along with this software; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\"\"\"\nimport unittest\nimport jsonrpc\nfrom types import *\n\nclass Service(object):\n    @jsonrpc.ServiceMethod\n    def echo(self, arg):\n        return arg\n\n\nclass ApacheRequestMockup(object):\n\n    def __init__(self, filename, fin, fout):\n        self.fin=fin\n        self.fout = fout\n        self.filename = filename\n        \n    def write(self,data):\n        self.fout.write(data)\n\n    def flush(self):\n        pass\n    \n    def read(self):\n        return self.fin.read()\n\nclass ModPyMockup(object):\n    def __init__(self):\n        self.apache=ApacheModuleMockup()\n\nclass ApacheModuleMockup(object):\n    def __getattr__(self, name):\n        return name\n    \n    def import_module(self, moduleName, log=1):\n        return Service()\n\n\n    \nclass  TestModPyWrapper(unittest.TestCase):\n\n    def setUp(self):\n        import sys\n        sys.modules['mod_python']  =ModPyMockup()\n        \n    def tearDown(self):\n        pass\n\n    def test_runHandler(self):\n        from StringIO import StringIO\n       \n        json=u'{\"method\":\"echo\",\"params\":[\"foobar\"], \"id\":\"\"}'\n        fin=StringIO(json)\n        fout=StringIO()\n        req = ApacheRequestMockup(__file__ , fin, fout)\n\n        jsonrpc.handler(req)\n\n        data = fout.getvalue()\n\n        self.assertEquals(jsonrpc.loads(data), {\"result\":\"foobar\", \"error\":None, \"id\":\"\"})\n\n    def test_ServiceImplementationNotFound(self):\n        from StringIO import StringIO\n       \n        json=u'{\"method\":\"echo\",\"params\":[\"foobar\"], \"id\":\"\"}'\n        fin=StringIO(json)\n        fout=StringIO()\n        req = ApacheRequestMockup(\"foobar\" , fin, fout)\n\n        rslt = jsonrpc.handler(req)\n        self.assertEquals(rslt, \"OK\")\n        data = fout.getvalue()\n\n        self.assertEquals(jsonrpc.loads(data), {u'id': '', u'result': None, u'error': {u'message': '', u'name': u'ServiceImplementaionNotFound'}} )\n\n        \n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/jsonrpc/_tests/test_proxy.py",
    "content": "\n\"\"\"\n  Copyright (c) 2007 Jan-Klaas Kollhof\n\n  This file is part of jsonrpc.\n\n  jsonrpc is free software; you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation; either version 2.1 of the License, or\n  (at your option) any later version.\n\n  This software is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public License\n  along with this software; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\"\"\"\n\nimport unittest\nimport jsonrpc\n\nimport urllib\n\nfrom StringIO import StringIO\n\nclass  TestProxy(unittest.TestCase):\n\n    def urlopen(self, url, data):\n        self.postdata = data\n        return StringIO(self.respdata) \n    \n    def setUp(self):\n        self.postdata=\"\"\n        self.urllib_openurl = urllib.urlopen\n        urllib.urlopen = self.urlopen\n        \n    def tearDown(self):\n        urllib.urlopen = self.urllib_openurl\n\n    def test_ProvidesProxyMethod(self):\n        s = jsonrpc.ServiceProxy(\"http://localhost/\")\n        self.assert_(callable(s.echo))\n\n    def test_MethodCallCallsService(self):\n        \n        s = jsonrpc.ServiceProxy(\"http://localhost/\")\n\n        self.respdata='{\"result\":\"foobar\",\"error\":null,\"id\":\"\"}'\n        echo = s.echo(\"foobar\")\n        self.assertEquals(self.postdata, jsonrpc.dumps({\"method\":\"echo\", 'params':['foobar'], 'id':'jsonrpc'}))\n        self.assertEquals(echo, 'foobar')\n\n        self.respdata='{\"result\":null,\"error\":\"MethodNotFound\",\"id\":\"\"}'\n        try:\n            s.echo(\"foobar\")\n        except jsonrpc.JSONRPCException,e:\n            self.assertEquals(e.error, \"MethodNotFound\")\n            "
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/jsonrpc/_tests/test_serviceHandler.py",
    "content": "\n\"\"\"\n  Copyright (c) 2007 Jan-Klaas Kollhof\n\n  This file is part of jsonrpc.\n\n  jsonrpc is free software; you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation; either version 2.1 of the License, or\n  (at your option) any later version.\n\n  This software is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public License\n  along with this software; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\"\"\"\n\n\n\n\nimport unittest\nimport jsonrpc\nfrom types import *\n\n\nclass Service(object):\n    @jsonrpc.ServiceMethod\n    def echo(self, arg):\n        return arg\n\n    def not_a_serviceMethod(self):\n        pass\n    \n    @jsonrpc.ServiceMethod\n    def raiseError(self):\n        raise Exception(\"foobar\")\n\nclass Handler(jsonrpc.ServiceHandler):\n    def __init__(self, service):\n        self.service=service\n\n    def translateRequest(self, data):\n        self._requestTranslated=True\n        return jsonrpc.ServiceHandler.translateRequest(self, data)\n    \n    def findServiceEndpoint(self, name):\n        self._foundServiceEndpoint=True\n        return jsonrpc.ServiceHandler.findServiceEndpoint(self, name)\n\n    def invokeServiceEndpoint(self, meth, params):\n        self._invokedEndpoint=True\n        return jsonrpc.ServiceHandler.invokeServiceEndpoint(self, meth, params)\n\n    def translateResult(self, result, error, id_):\n        self._resultTranslated=True\n        return jsonrpc.ServiceHandler.translateResult(self, result, error,  id_)\n\n\n\nclass  TestServiceHandler(unittest.TestCase):\n\n    def setUp(self):\n        self.service = Service()\n        \n    def tearDown(self):\n        pass\n\n    def test_RequestProcessing(self):\n        handler = Handler(self.service)\n        json=jsonrpc.dumps({\"method\":\"echo\", 'params':['foobar'], 'id':''})\n        \n        result  = handler.handleRequest(json)\n        self.assert_(handler._requestTranslated)\n        self.assert_(handler._foundServiceEndpoint)\n        self.assert_(handler._invokedEndpoint)\n        self.assert_(handler._resultTranslated)\n\n    def test_translateRequest(self):\n        handler = Handler(self.service)\n        json=jsonrpc.dumps({\"method\":\"echo\", 'params':['foobar'], 'id':''})\n        req = handler.translateRequest(json)\n        self.assertEquals(req['method'], \"echo\")\n        self.assertEquals(req['params'],['foobar'])\n        self.assertEquals(req['id'],'')\n\n    def test_findServiceEndpoint(self):\n        handler = Handler(self.service)\n        self.assertRaises(jsonrpc.ServiceMethodNotFound, handler.findServiceEndpoint, \"notfound\")\n        self.assertRaises(jsonrpc.ServiceMethodNotFound, handler.findServiceEndpoint, \"not_a_serviceMethod\")\n        meth = handler.findServiceEndpoint(\"echo\")\n        self.assertEquals(self.service.echo, meth)\n\n    def test_invokeEndpoint(self):\n        handler = Handler(self.service)\n        meth = handler.findServiceEndpoint(\"echo\")\n        rslt = handler.invokeServiceEndpoint(meth, ['spam'])\n        self.assertEquals(rslt, 'spam')\n\n    def test_translateResults(self):\n        handler=Handler(self.service)\n        data=handler.translateResult(\"foobar\", None,  \"spam\")\n        self.assertEquals(jsonrpc.loads(data), {\"result\":\"foobar\",\"id\":\"spam\",\"error\":None})\n\n    def test_translateError(self):\n        handler=Handler(self.service)\n        exc = Exception()\n        data=handler.translateResult(None, exc, \"id\")\n        self.assertEquals(jsonrpc.loads(data), {\"result\":None,\"id\":\"id\",\"error\":{\"name\":\"Exception\", \"message\":\"\"}})\n\n    def test_translateUnencodableResults(self):\n        handler=Handler(self.service)\n        data=handler.translateResult(self, None, \"spam\")\n        self.assertEquals(jsonrpc.loads(data), {\"result\":None,\"id\":\"spam\",\"error\":{\"name\":\"JSONEncodeException\", \"message\":\"Result Object Not Serializable\"}})\n\n    def test_handleRequestEcho(self):\n        handler=Handler(self.service)\n        json=jsonrpc.dumps({\"method\":\"echo\", 'params':['foobar'], 'id':''})\n        result = handler.handleRequest(json)\n        self.assertEquals(jsonrpc.loads(result), jsonrpc.loads('{\"result\":\"foobar\", \"error\":null, \"id\":\"\"}'))\n\n    def test_handleRequestMethodNotFound(self):\n        handler=Handler(self.service)\n        json=jsonrpc.dumps({\"method\":\"not_found\", 'params':['foobar'], 'id':''})\n        result = handler.handleRequest(json)\n        self.assertEquals(jsonrpc.loads(result), {\"result\":None, \"error\":{\"name\":\"ServiceMethodNotFound\", \"message\":\"\"}, \"id\":\"\"})\n\n    def test_handleRequestMethodNotAllowed(self):\n        handler=Handler(self.service)\n        json=jsonrpc.dumps({\"method\":\"not_a_ServiceMethod\", 'params':['foobar'], 'id':''})\n        result = handler.handleRequest(json)\n        self.assertEquals(jsonrpc.loads(result), {\"result\":None, \"error\":{\"name\":\"ServiceMethodNotFound\", \"message\":\"\"}, \"id\":\"\"})\n\n    def test_handleRequestMethodRaiseError(self):\n        handler=Handler(self.service)\n        json=jsonrpc.dumps({\"method\":\"raiseError\", 'params':[], 'id':''})\n        result = handler.handleRequest(json)\n        self.assertEquals(jsonrpc.loads(result), {\"result\":None, \"error\":{\"name\":\"Exception\", \"message\":\"foobar\"}, \"id\":\"\"})\n\n    def test_handleBadRequestData(self):\n        handler=Handler(self.service)\n        json = \"This is not a JSON-RPC request\"\n        result = handler.handleRequest(json)\n        self.assertEquals(jsonrpc.loads(result), {\"result\":None, \"error\":{\"name\":\"ServiceRequestNotTranslatable\", \"message\":json}, \"id\":\"\"})\n\n    def test_handleBadRequestObject(self):\n        handler=Handler(self.service)\n        json = \"{}\"\n        result = handler.handleRequest(json)\n        self.assertEquals(jsonrpc.loads(result), {\"result\":None, \"error\":{\"name\":\"BadServiceRequest\", \"message\":json}, \"id\":\"\"})\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/jsonrpc/cgiwrapper.py",
    "content": "import sys, os\nfrom jsonrpc import ServiceHandler\n\nclass CGIServiceHandler(ServiceHandler):\n    def __init__(self, service):\n        if service == None:\n            import __main__ as service\n\n        ServiceHandler.__init__(self, service)\n\n    def handleRequest(self, fin=None, fout=None, env=None):\n        if fin==None:\n            fin = sys.stdin\n        if fout==None:\n            fout = sys.stdout\n        if env == None:\n            env = os.environ\n        \n        try:\n            contLen=int(env['CONTENT_LENGTH'])\n            data = fin.read(contLen)\n        except Exception, e:\n            data = \"\"\n\n        resultData = ServiceHandler.handleRequest(self, data)\n        \n        response = \"Content-Type: text/plain\\n\"\n        response += \"Content-Length: %d\\n\\n\" % len(resultData)\n        response += resultData\n        \n        #on windows all \\n are converted to \\r\\n if stdout is a terminal and  is not set to binary mode :(\n        #this will then cause an incorrect Content-length.\n        #I have only experienced this problem with apache on Win so far.\n        if sys.platform == \"win32\":\n            try:\n                import  msvcrt\n                msvcrt.setmode(fout.fileno(), os.O_BINARY)\n            except:\n                pass\n        #put out the response\n        fout.write(response)\n        fout.flush()\n\ndef handleCGI(service=None, fin=None, fout=None, env=None):\n    CGIServiceHandler(service).handleRequest(fin, fout, env)"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/jsonrpc/json.py",
    "content": "\n\"\"\"\n  Copyright (c) 2007 Jan-Klaas Kollhof\n\n  This file is part of jsonrpc.\n\n  jsonrpc is free software; you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation; either version 2.1 of the License, or\n  (at your option) any later version.\n\n  This software is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public License\n  along with this software; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\"\"\"\n\nfrom types import *\nimport re\n\nCharReplacements ={\n        '\\t': '\\\\t',\n        '\\b': '\\\\b',\n        '\\f': '\\\\f',\n        '\\n': '\\\\n',\n        '\\r': '\\\\r',\n        '\\\\': '\\\\\\\\',\n        '/': '\\\\/',\n        '\"': '\\\\\"'}\n\nEscapeCharToChar = {\n        't': '\\t',\n        'b': '\\b',\n        'f': '\\f',\n        'n': '\\n',\n        'r': '\\r',\n        '\\\\': '\\\\',\n        '/': '/',\n        '\"' : '\"'}\n\nStringEscapeRE= re.compile(r'[\\x00-\\x19\\\\\"/\\b\\f\\n\\r\\t]')\nDigits = ['0', '1', '2','3','4','5','6','7','8','9']\n\n\nclass JSONEncodeException(Exception):\n    def __init__(self, obj):\n        Exception.__init__(self)\n        self.obj = obj\n\n    def __str__(self):\n       return \"Object not encodeable: %s\" % self.obj\n\n       \nclass JSONDecodeException(Exception):\n    def __init__(self, message):\n        Exception.__init__(self)\n        self.message = message\n\n    def __str__(self):\n       return self.message\n\n    \ndef escapeChar(match):\n    c=match.group(0)\n    try:\n        replacement = CharReplacements[c]\n        return replacement\n    except KeyError:\n        d = ord(c)\n        if d < 32:\n            return '\\\\u%04x' % d\n        else:\n            return c\n\ndef dumps(obj):\n    return unicode(\"\".join([part for part in dumpParts (obj)]))\n\ndef dumpParts (obj):\n    objType = type(obj)\n    if obj == None:\n       yield u'null'\n    elif objType is BooleanType:\n        if obj:\n            yield u'true'\n        else:\n            yield u'false'\n    elif objType is DictionaryType:\n        yield u'{'\n        isFirst=True\n        for (key, value) in obj.items():\n            if isFirst:\n                isFirst=False\n            else:\n                yield u\",\"\n            yield u'\"' + StringEscapeRE.sub(escapeChar, key) +u'\":'\n            for part in dumpParts (value):\n                yield part\n        yield u'}'\n    elif objType in StringTypes:\n        yield u'\"' + StringEscapeRE.sub(escapeChar, obj) +u'\"'\n\n    elif objType in [TupleType, ListType, GeneratorType]:\n        yield u'['\n        isFirst=True\n        for item in obj:\n            if isFirst:\n                isFirst=False\n            else:\n                yield u\",\"\n            for part in dumpParts (item):\n                yield part\n        yield u']'\n    elif objType in [IntType, LongType, FloatType]:\n        yield unicode(obj)\n    else:\n        raise JSONEncodeException(obj)\n    \n\ndef loads(s):\n    stack = []\n    chars = iter(s)\n    value = None\n    currCharIsNext=False\n\n    try:\n        while(1):\n            skip = False\n            if not currCharIsNext:\n                c = chars.next()\n            while(c in [' ', '\\t', '\\r','\\n']):\n                c = chars.next()\n            currCharIsNext=False\n            if c=='\"':\n                value = ''\n                try:\n                    c=chars.next()\n                    while c != '\"':\n                        if c == '\\\\':\n                            c=chars.next()\n                            try:\n                                value+=EscapeCharToChar[c]\n                            except KeyError:\n                                if c == 'u':\n                                    hexCode = chars.next() + chars.next() + chars.next() + chars.next()\n                                    value += unichr(int(hexCode,16))\n                                else:\n                                    raise JSONDecodeException(\"Bad Escape Sequence Found\")\n                        else:\n                            value+=c\n                        c=chars.next()\n                except StopIteration:\n                    raise JSONDecodeException(\"Expected end of String\")\n            elif c == '{':\n                stack.append({})\n                skip=True\n            elif c =='}':\n                value = stack.pop()\n            elif c == '[':\n                stack.append([])\n                skip=True\n            elif c == ']':\n                value = stack.pop()\n            elif c in [',',':']:\n                skip=True\n            elif c in Digits or c == '-':\n                digits=[c]\n                c = chars.next()\n                numConv = int\n                try:\n                    while c in Digits:\n                        digits.append(c)\n                        c = chars.next()\n                    if c == \".\":\n                        numConv=float\n                        digits.append(c)\n                        c = chars.next()\n                        while c in Digits:\n                            digits.append(c)\n                            c = chars.next()\n                        if c.upper() == 'E':\n                            digits.append(c)\n                            c = chars.next()\n                            if c in ['+','-']:\n                                digits.append(c)\n                                c = chars.next()\n                                while c in Digits:\n                                    digits.append(c)\n                                    c = chars.next()\n                            else:\n                                raise JSONDecodeException(\"Expected + or -\")\n                except StopIteration:\n                    pass\n                value = numConv(\"\".join(digits))\n                currCharIsNext=True\n\n            elif c in ['t','f','n']:\n                kw = c+ chars.next() + chars.next() + chars.next()\n                if kw == 'null':\n                    value = None\n                elif kw == 'true':\n                    value = True\n                elif kw == 'fals' and chars.next() == 'e':\n                    value = False\n                else:\n                    raise JSONDecodeException('Expected Null, False or True')\n            else:\n                raise JSONDecodeException('Expected []{},\" or Number, Null, False or True')\n\n            if not skip:\n                if len(stack):\n                    top = stack[-1]\n                    if type(top) is ListType:\n                        top.append(value)\n                    elif type(top) is DictionaryType:\n                        stack.append(value)\n                    elif type(top)  in StringTypes:\n                        key = stack.pop()\n                        stack[-1][key] = value\n                    else:\n                        raise JSONDecodeException(\"Expected dictionary key, or start of a value\")\n                else:\n                    return value\n    except StopIteration:\n         raise JSONDecodeException(\"Unexpected end of JSON source\")\n\n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/jsonrpc/modpywrapper.py",
    "content": "import sys, os\nfrom jsonrpc import ServiceHandler, ServiceException\n\n\nclass ServiceImplementaionNotFound(ServiceException):\n    pass\n\n\nclass ModPyServiceHandler(ServiceHandler):\n    def __init__(self, req):\n        self.req = req\n        ServiceHandler.__init__(self, None)\n\n\n    def findServiceEndpoint(self, name):\n        req = self.req\n\n        (modulePath, fileName) = os.path.split(req.filename)\n        (moduleName, ext) = os.path.splitext(fileName)\n        \n        if not os.path.exists(os.path.join(modulePath, moduleName + \".py\")):\n            raise ServiceImplementaionNotFound()\n        else:\n            if not modulePath in sys.path:\n                sys.path.insert(0, modulePath)\n\n            from mod_python import apache\n            module = apache.import_module(moduleName, log=1)\n            \n            if hasattr(module, \"service\"):\n                self.service = module.service\n            elif hasattr(module, \"Service\"):\n                self.service = module.Service()\n            else:\n                self.service = module\n\n        return ServiceHandler.findServiceEndpoint(self, name)\n            \n    \n    def handleRequest(self, data):\n        self.req.content_type = \"text/plain\"\n        data = self.req.read()\n        resultData = ServiceHandler.handleRequest(self, data)\n        self.req.write(resultData)\n        self.req.flush()\n\ndef handler(req):\n    from mod_python import apache\n    ModPyServiceHandler(req).handleRequest(req)\n    return apache.OK\n    \n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/jsonrpc/proxy.py",
    "content": "\n\"\"\"\n  Copyright (c) 2007 Jan-Klaas Kollhof\n\n  This file is part of jsonrpc.\n\n  jsonrpc is free software; you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation; either version 2.1 of the License, or\n  (at your option) any later version.\n\n  This software is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public License\n  along with this software; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\"\"\"\n\nimport urllib\nfrom jsonrpc.json import dumps, loads\n\nclass JSONRPCException(Exception):\n    def __init__(self, rpcError):\n        Exception.__init__(self)\n        self.error = rpcError\n        \nclass ServiceProxy(object):\n    def __init__(self, serviceURL, serviceName=None):\n        self.__serviceURL = serviceURL\n        self.__serviceName = serviceName\n\n    def __getattr__(self, name):\n        if self.__serviceName != None:\n            name = \"%s.%s\" % (self.__serviceName, name)\n        return ServiceProxy(self.__serviceURL, name)\n\n    def __call__(self, *args):\n         postdata = dumps({\"method\": self.__serviceName, 'params': args, 'id':'jsonrpc'})\n         respdata = urllib.urlopen(self.__serviceURL, postdata).read()\n         resp = loads(respdata)\n         if resp['error'] != None:\n             raise JSONRPCException(resp['error'])\n         else:\n             return resp['result']\n         \n\n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/jsonrpc/serviceHandler.py",
    "content": "\n\"\"\"\n  Copyright (c) 2007 Jan-Klaas Kollhof\n\n  This file is part of jsonrpc.\n\n  jsonrpc is free software; you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation; either version 2.1 of the License, or\n  (at your option) any later version.\n\n  This software is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public License\n  along with this software; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\"\"\"\n\nfrom jsonrpc import loads, dumps, JSONEncodeException\n\n\ndef ServiceMethod(fn):\n    fn.IsServiceMethod = True\n    return fn\n\nclass ServiceException(Exception):\n    pass\n\nclass ServiceRequestNotTranslatable(ServiceException):\n    pass\n\nclass BadServiceRequest(ServiceException):\n    pass\n\nclass ServiceMethodNotFound(ServiceException):\n    def __init__(self, name):\n        self.methodName=name\n\nclass ServiceHandler(object):\n\n    def __init__(self, service):\n        self.service=service\n    \n    def handleRequest(self, json):\n        err=None\n        result = None\n        id_=''\n        \n        try:\n            req = self.translateRequest(json)\n        except ServiceRequestNotTranslatable, e:\n            err = e\n            req={'id':id_}\n\n        if err==None:\n            try:\n                id_ = req['id']\n                methName = req['method']\n                args = req['params']\n            except:\n                err = BadServiceRequest(json)\n                \n        if err == None:\n            try:\n                meth = self.findServiceEndpoint(methName)\n            except Exception, e:\n                err = e\n\n        if err == None:\n            try:\n                result = self.invokeServiceEndpoint(meth, args)\n            except Exception, e:\n                err = e\n\n        resultdata = self.translateResult(result, err, id_)\n\n        return resultdata\n\n    def translateRequest(self, data):\n        try:\n            req = loads(data)\n        except:\n            raise ServiceRequestNotTranslatable(data)\n        return req\n     \n    def findServiceEndpoint(self, name):\n        try:\n            meth = getattr(self.service, name)\n            if getattr(meth, \"IsServiceMethod\"):\n                return meth\n            else:\n                raise ServiceMethodNotFound(name)\n        except AttributeError:\n            raise ServiceMethodNotFound(name)\n\n    def invokeServiceEndpoint(self, meth, args):\n        return meth(*args)\n\n    def translateResult(self, rslt, err, id_):\n        if err != None:\n            err = {\"name\": err.__class__.__name__, \"message\":err.message}\n            rslt = None\n\n        try:\n            data = dumps({\"result\":rslt,\"id\":id_,\"error\":err})\n        except JSONEncodeException, e:\n            err = {\"name\": \"JSONEncodeException\", \"message\":\"Result Object Not Serializable\"}\n            data = dumps({\"result\":None, \"id\":id_,\"error\":err})\n            \n        return data"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/run-tests.py",
    "content": "#!/usr/bin/env python\n\n\"\"\"\n  Copyright (c) 2007 Jan-Klaas Kollhof\n\n  This file is part of jsonrpc.\n\n  jsonrpc is free software; you can redistribute it and/or modify\n  it under the terms of the GNU Lesser General Public License as published by\n  the Free Software Foundation; either version 2.1 of the License, or\n  (at your option) any later version.\n\n  This software is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public License\n  along with this software; if not, write to the Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\"\"\"\n\n\nimport unittest\nimport os\n\n\nfrom jsonrpc import _tests\n\nif __name__ == \"__main__\":\n\n    testPath = os.path.split(_tests.__file__)[0]\n    testModules = []\n    for fileName in os.listdir(testPath):\n        if fileName[-3:] == '.py' and fileName != '__init__.py':\n            testModules.append('jsonrpc._tests.%s' % fileName[:-3])\n\n    suite = unittest.TestLoader().loadTestsFromNames(testModules)\n\n    unittest.TextTestRunner(verbosity=5).run(suite)\n    \n"
  },
  {
    "path": "ICARUS-LX150/MiningSoftware/python-jsonrpc/setup.py",
    "content": "#!/usr/bin/env python\n\nfrom distutils.core import setup\n\nsetup(name = \"jsonrpc\",\n    version = \"0.01\",\n    description = \"A json-rpc package which implements JSON-RPC over HTTP.\",\n    keywords = \"JSON RPC\",\n    author = \"Jan-Klaas Kollhof\",\n    url = \"http://json-rpc.org/wiki/python-json-rpc\",\n    license = \"LGPL\",\n    long_description = \"\"\"\"\"\",\n    packages = ['jsonrpc']\n)"
  },
  {
    "path": "ICARUS-LX150/README.txt",
    "content": "This is a multicore proof of concept litecoin miner for ngzhang's Icarus/Lancelot board.\n\nI targeted this board as it is well documented at https://github.com/ngzhang/Icarus\n\nOriginally I used ngzhang's serial interface code as a basis, but due to concerns about\nGPL compatability, I currently use teknohog's directly (ngzhang's is based on teknokog's)\nhttps://github.com/teknohog/Open-Source-FPGA-Bitcoin-Miner/tree/master/projects/Xilinx_cluster_cgminer\n\nThe current version is based on experimental/LX150-SLOWSIXTEEN-A\n\nSet the number of cores in ltcaminer_icarus.v parameter LOCAL_MINERS. Eight cores is the\ncurrent maximum, do not use a higher value as the nonce distribution will fail. NB The\ncurrent code will only build with a maximum of two cores due to resource usage.\n\nA custom driver is needed as we use the full block header, not midstate. This is based on\nminer.py from the original fpgaminer xilinx project, modified to send the full 80 bytes of\nthe block header plus the target so as to support variable difficulty pools. This is\nprovided in MiningSoftware, see MiningSoftware/README.txt for details. Note that the\nclockrate is set at runtime. By default this is 25MHz, you should increase this until\nthe error rate becomes unacceptable. 50MHz was achievable with my lancelot board.\n\nThe project was built in PlanAhead version 14.4 (windows, 32 bits) using the following\nmodified synthesis settings (strategy defined in Tools/Options) ...\n\nregister balancing = yes\nregister duplication = yes (already in default)\nresource sharing = no\nequivalent register removal = no\n\nDevice is xc6slx150-fgg484-2 (speed grade 2). A lot of warnings are produced (sorry!)\n\nA bitstream is provided on dropbox, see ../bitstream.txt. A xilinx platform cable plus an\ninstallation of the Impact software will be needed to upload the bitstream.\n\nTest results on dual-fpga Lancelot RevB board, using stratum proxy server with askrate of\n2 seconds, measured at pool using conversion kHash/sec = (diff_1_shares/hr * 65536 / 3.6M)\nAt 50MHz (set dynamically) lancelot hashrate 33kHash/sec (16 per LX150, 8 per core).\n"
  },
  {
    "path": "ICARUS-LX150/dyn_pll_ctrl.v",
    "content": "module dyn_pll_ctrl # (parameter SPEED_MHZ = 25, parameter SPEED_LIMIT = 100, parameter SPEED_MIN = 25, parameter OSC_MHZ = 100)\n\t(clk,\n\tclk_valid,\n\tspeed_in,\n\tstart,\n\tprogclk,\n\tprogdata,\n\tprogen,\n\treset,\n\tlocked,\n\tstatus);\n\n\tinput clk;\t\t\t\t// NB Assumed to be 12.5MHz uart_clk\n\tinput clk_valid;\t\t// Drive from LOCKED output of first dcm (ie uart_clk valid)\n\tinput [7:0] speed_in;\n\tinput start;\n\toutput reg progclk = 0;\n\toutput reg progdata = 0;\n\toutput reg progen = 0;\n\toutput reg reset = 0;\n\tinput locked;\n\tinput [2:1] status;\n\n\t// NB spec says to use (dval-1) and (mval-1), but I don't think we need to be that accurate\n\t//    and this saves an adder. Feel free to amend it.\n\treg [23:0] watchdog = 0;\n\treg [7:0] state = 0;\n\treg [7:0] dval = OSC_MHZ;\t// Osc clock speed (hence mval scales in MHz)\n\treg [7:0] mval = SPEED_MHZ;\n\treg start_d1 = 0;\n\t\n\talways @ (posedge clk)\n\tbegin\n\t\tprogclk <= ~progclk;\n\t\tstart_d1 <= start;\n\t\treset <= 1'b0;\n\t\t\n\t\t// Watchdog is just using locked, perhaps also need | ~status[2]\n\t\tif (locked)\n\t\t\twatchdog <= 0;\n\t\telse\n\t\t\twatchdog <= watchdog + 1'b1;\n\t\t\n\t\tif (watchdog[23])\t\t// Approx 670mS at 12.5MHz - NB spec is 5ms to lock at >50MHz CLKIN (50ms at <50MHz CLKIN)\n\t\tbegin\t\t\t\t\t// but allow longer just in case\n\t\t\twatchdog <= 0;\n\t\t\treset <= 1'b1;\t\t// One cycle at 12.5MHz should suffice (requirment is 3 CLKIN at 100MHz)\n\t\tend\n\t\t\n\t\tif (~clk_valid)\t\t\t// Try not to run while clk is unstable\n\t\tbegin\n\t\t\tprogen <= 0;\n\t\t\tprogdata <= 0;\n\t\t\tstate <= 0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\n\t\t\t// The documentation is unclear as to whether the DCM loads data on positive or negative edge. The timing\n\t\t\t// diagram unhelpfully shows data changing on the positive edge, which could mean either its sampled on\n\t\t\t// negative, or it was clocked on positive! However the following (WRONGLY) says NEGATIVE ...\n\t\t\t// http://forums.xilinx.com/t5/Spartan-Family-FPGAs/Spartan6-DCM-CLKGEN-does-PROGCLK-have-a-maximum-period-minimum/td-p/175642\n\t\t\t// BUT this can lock up the DCM, positive clock seems more reliable (but it can still lock up for low values of M, eg 2).\n\t\t\t// Added SPEED_MIN to prevent this (and positive clock is correct, after looking at other implementations eg ztex/theseven)\n\t\t\n\t\t\tif ((start || start_d1) && state==0 && speed_in >= SPEED_MIN && speed_in <= SPEED_LIMIT && progclk==1)\t// positive clock\n\t\t\t// if ((start || start_d1) && state==0 && speed_in >= SPEED_MIN && speed_in <= SPEED_LIMIT && progclk==0)\t// negative clock\n\t\t\tbegin\n\t\t\t\tprogen <= 0;\n\t\t\t\tprogdata <= 0;\n\t\t\t\tmval <= speed_in;\n\t\t\t\tdval <= OSC_MHZ;\n\t\t\t\tstate <= 1;\n\t\t\tend\n\t\t\tif (state != 0)\n\t\t\t\tstate <= state + 1'd1;\n\t\t\tcase (state)\t\t// Even values to sync with progclk\n\t\t\t\t// Send D\n\t\t\t\t2: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\t\tprogdata <= 1;\n\t\t\t\tend\n\t\t\t\t4: begin\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t6,8,10,12,14,16,18,20: begin\n\t\t\t\t\tprogdata <= dval[0];\n\t\t\t\t\tdval[6:0] <= dval[7:1];\n\t\t\t\tend\n\t\t\t\t22: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t// Send M\n\t\t\t\t32: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\t\tprogdata <= 1;\n\t\t\t\tend\n\t\t\t\t36,38,40,42,44,46,48,50: begin\n\t\t\t\t\tprogdata <= mval[0];\n\t\t\t\t\tmval[6:0] <= mval[7:1];\n\t\t\t\tend\n\t\t\t\t52: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t// Send GO - NB 1 clock cycle\n\t\t\t\t62: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\tend\n\t\t\t\t64: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\tend\n\t\t\t\t// We should wait on progdone/locked, but just go straight back to idle\n\t\t\t\t254: begin\n\t\t\t\t\tstate <= 0;\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n\tend\nendmodule\n"
  },
  {
    "path": "ICARUS-LX150/hub_core.v",
    "content": "module hub_core (uart_clk, new_nonces, golden_nonce, serial_send, serial_busy, slave_nonces);\n   parameter SLAVES = 2;\n\n   input uart_clk;\n   \n   input [SLAVES-1:0] new_nonces;\n   input [SLAVES*32-1:0] slave_nonces;\n   output [31:0] \t golden_nonce;\n   output \t\t serial_send;\n   input \t\t serial_busy;\n\n   reg \t\t\t serial_send_reg = 0;\n   assign serial_send = serial_send_reg;\n  \n   // Remember all nonces, even when they come too close together, and\n   // send them whenever the uplink is ready\n   reg [SLAVES-1:0] \tnew_nonces_flag = 0;\n   \n   // Replace the tedious if-else chain for input ports with a\n   // continuously running selector. This may seem slow/inefficient\n   // for a large hub, but it is still insanely faster than the serial\n   // port we are driving. Also, due to simplicity, it should be more\n   // robust for big hubs with fast clocks.\n\n   function integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n      input integer value;\n      begin\n      value = value-1;\n      for (clog2=0; value>0; clog2=clog2+1)\n      value = value>>1;\n      end\n   endfunction\n\n   reg [clog2(SLAVES)+1:0] port_counter = 0;\n   reg [SLAVES*32-1:0] \t    slave_nonces_shifted = 0;\n   assign golden_nonce = slave_nonces_shifted[31:0];\n\n   // When sending, mark nonces to be cleared during next clock cycle\n   reg [SLAVES-1:0] \t    clear_nonces = 0;\n   \n   always @(posedge uart_clk)\n     begin\n\t// Raise flags when new nonces appear; lower those that have\n\t// been sent\n\tnew_nonces_flag <= (new_nonces_flag & ~clear_nonces) | new_nonces;\n\n\tif (port_counter == SLAVES-1)\n\t  port_counter <= 0;\n\telse\n\t  port_counter <= port_counter + 1;\n\t\n\t// Send results one at a time, mark to be cleared\n\t// kramble - the optimiser removes all but the low 32 bits of slave_nonces_shifted since\n\t// the following code implements a multiplexor on slave_nonces input, NOT an actual shifter.\n\t// This is also the behaviour of nghzang's github code, so I'm not going to change it.\n\tif (!serial_busy && new_nonces_flag[port_counter])\n\t  begin\n\t     slave_nonces_shifted <= slave_nonces >> port_counter*32;\n\t     serial_send_reg <= 1;\n\t     clear_nonces[port_counter] <= 1;\n\t  end\n\telse \n\t  begin\n\t     serial_send_reg <= 0;\n\t     clear_nonces <= 0;\n\t  end\n     end\n\nendmodule // hub_core\n\n"
  },
  {
    "path": "ICARUS-LX150/ltcminer_icarus.ucf",
    "content": "# Based on https://github.com/ngzhang/Icarus/blob/master/FPGA_project/Src/fpgaminer_top.ucf\n\nNET \"hash_clk\" TNM_NET = \"hash_clk\";\nNET \"pbkdf_clk\" TNM_NET = \"pbkdf_clk\";\nNET \"uart_clk\" TNM_NET = \"uart_clk\";\n\n# 10MHz hash_clk (it may route better specifying a slightly slower clock)\nTIMESPEC TS_hash_clk = PERIOD \"hash_clk\" 10 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\n# 50MHz pbkdf_clk\nTIMESPEC TS_pbkdf_clk = PERIOD \"pbkdf_clk\" 50 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\n# 12.5MHz uart_clk\nTIMESPEC TS_uart_clk = PERIOD \"uart_clk\" 12.5 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\nNET \"osc_clk\" LOC = J1 | IOSTANDARD = LVCMOS33;\n\n# serial port receive & transmit\nNET \"RxD\" LOC = D1 | IOSTANDARD = LVCMOS33;\nNET \"TxD\" LOC = B1 | IOSTANDARD = LVCMOS33;\n\n# TTL level serial port: ja3 = rxd, ja2 = txd\nNET \"extminer_txd[0]\" LOC = D22 | IOSTANDARD = LVCMOS33;\nNET \"extminer_rxd[0]\" LOC = B22 | IOSTANDARD = LVCMOS33;\n\nNET \"led[0]\" LOC = A18 | IOSTANDARD = LVCMOS33;\nNET \"led[1]\" LOC = B18 | IOSTANDARD = LVCMOS33;\nNET \"led[2]\" LOC = A17 | IOSTANDARD = LVCMOS33;\nNET \"led[3]\" LOC = A16 | IOSTANDARD = LVCMOS33;\n\nNET \"dip[0]\" LOC = A4 | IOSTANDARD = LVCMOS33;\nNET \"dip[1]\" LOC = D6 | IOSTANDARD = LVCMOS33;\nNET \"dip[2]\" LOC = C6 | IOSTANDARD = LVCMOS33;\nNET \"dip[3]\" LOC = C8 | IOSTANDARD = LVCMOS33;\n\nNET \"TMP_SCL\" LOC = C1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_SDA\" LOC = E1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_ALERT\" LOC = C3 | IOSTANDARD = LVCMOS33 | PULLUP;\n"
  },
  {
    "path": "ICARUS-LX150/ltcminer_icarus.v",
    "content": "/* ltcminer_icarus.v copyright kramble 2013\n * Based on https://github.com/teknohog/Open-Source-FPGA-Bitcoin-Miner/tree/master/projects/Xilinx_cluster_cgminer\n * Hub code for a cluster of miners using async links\n * by teknohog\n */\n\n`include \"../source/sha-256-functions.v\"\n`include \"../source/sha256_transform.v\"\n\nmodule ltcminer_icarus (osc_clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n// NB SPEED_MHZ resolution is 5MHz steps to keep pll divide ratio sensible. Change the divider in xilinx_pll.v if you\n// want other steps (1MHz is not sensible as it requires divide 100 which is not in the allowed range 1..32 for DCM_SP)\n// New dyn_pll has 1MHz resolution and can be changed by sending a specific getwork packet (uses top bytes of target)\n\n`define USE_DYN_PLL\t\t// Enable new dyn_pll\n\n`ifdef SPEED_MHZ\n\tparameter SPEED_MHZ = `SPEED_MHZ;\n`else\n\tparameter SPEED_MHZ = 25;\t\t\t\t\t\t// Default to slow, use dynamic config to ramp up in realtime\n`endif\n\n`ifdef SPEED_LIMIT\n\tparameter SPEED_LIMIT = `SPEED_LIMIT;\t\t\t// Fastest speed accepted by dyn_pll config\n`else\n\tparameter SPEED_LIMIT = 100;\t\t\t\t\t// Deliberately conservative, increase at own risk\n`endif\n\n`ifdef SPEED_MIN\n\tparameter SPEED_MIN = `SPEED_MIN;\t\t\t\t// Slowest speed accepted by dyn_pll config (CARE can lock up if too low)\n`else\n\tparameter SPEED_MIN = 10;\n`endif\n\n`ifdef SERIAL_CLK\n\tparameter comm_clk_frequency = `SERIAL_CLK;\n`else\n\tparameter comm_clk_frequency = 12_500_000;\t\t// 100MHz divide 8\n`endif\n\n`ifdef BAUD_RATE\n\tparameter BAUD_RATE = `BAUD_RATE;\n`else\n\tparameter BAUD_RATE = 115_200;\n`endif\n\n// kramble - nonce distribution is crude using top 4 bits of nonce so max LOCAL_MINERS = 8\n// teknohog's was more sophisticated, but requires modification of hashcore.v\n\n// Miners on the same FPGA with this hub\n`ifdef LOCAL_MINERS\n\tparameter LOCAL_MINERS = `LOCAL_MINERS;\n`else\n\tparameter LOCAL_MINERS = 2;\t\t\t\t\t\t// One to four cores (configures ADDRBITS automatically)\n`endif\n\n`ifdef ADDRBITS\n\tparameter ADDRBITS = `ADDRBITS;\t\t\t\t\t// Override for simulation or a quick ISE build (eg one 10 bit core)\n`else\n\tparameter ADDRBITS = 12 - clog2(LOCAL_MINERS);\t// Automatically selects largest RAM that will fit LX150\n`endif\n\n// kramble - nonce distribution only works for a single external port \n`ifdef EXT_PORTS\n\tparameter EXT_PORTS = `EXT_PORTS;\n`else\n\tparameter EXT_PORTS = 1;\n`endif\n\n\tlocalparam SLAVES = LOCAL_MINERS + EXT_PORTS;\n\n\tinput osc_clk;\n\twire hash_clk, uart_clk, pbkdf_clk;\n\n`ifdef USE_DYN_PLL\n\twire first_dcm_locked, dcm_progclk, dcm_progdata, dcm_progen, dcm_reset, dcm_progdone, dcm_locked;\n\twire [2:1] dcm_status;\n`endif\n\n`ifndef SIM\n\t`ifdef USE_DYN_PLL\n\t\tdyn_pll # (.SPEED_MHZ(SPEED_MHZ)) dyn_pll_blk\n\t\t\t(osc_clk, \n\t\t\tpbkdf_clk, \n\t\t\thash_clk, \n\t\t\tuart_clk,\n\t\t\tfirst_dcm_locked,\n\t\t\tdcm_progclk,\n\t\t\tdcm_progdata,\n\t\t\tdcm_progen,\n\t\t\tdcm_reset,\n\t\t\tdcm_progdone,\n\t\t\tdcm_locked,\n\t\t\tdcm_status);\n\t`else\n\t\tmain_pll # (.SPEED_MHZ(SPEED_MHZ)) pll_blk (.CLKIN_IN(osc_clk), .CLKFX_OUT(hash_clk), .CLKDV_OUT(uart_clk));\n\t\tassign pbkdf_clk = uart_clk;\n\t`endif\n`else\n\tassign hash_clk = osc_clk;\n\tassign uart_clk = osc_clk;\n\tassign pbkdf_clk = osc_clk;\n\t`ifdef USE_DYN_PLL\n\t\tassign first_dcm_locked = 1'b1;\n\t\tassign dcm_progdone = 1'b1;\n\t\tassign dcm_locked = 1'b1;\n\t\tassign dcm_status = 0;\n\t`endif\t\n`endif\n\n`ifdef USE_DYN_PLL\n\treg [7:0] dyn_pll_speed = SPEED_MHZ;\n\treg dyn_pll_start = 0;\n\tparameter OSC_MHZ = 100;\t\t// Clock oscillator (used for divider ratio)\n\tdyn_pll_ctrl # (.SPEED_MHZ(SPEED_MHZ), .SPEED_LIMIT(SPEED_LIMIT), .SPEED_MIN(SPEED_MIN), .OSC_MHZ(OSC_MHZ)) dyn_pll_ctrl_blk\n\t\t(uart_clk,\t\t\t// NB uses uart_clk as its just osc/8 and should always be valid\n\t\tfirst_dcm_locked,\t// ... but we check it anyway\n\t\tdyn_pll_speed,\n\t\tdyn_pll_start,\n\t\tdcm_progclk,\n\t\tdcm_progdata,\n\t\tdcm_progen,\n\t\tdcm_reset,\n\t\tdcm_locked,\n\t\tdcm_status);\n`endif\n      \n\tinput TMP_SCL, TMP_SDA, TMP_ALERT;\t// Unused but set to PULLUP so as to avoid turning on the HOT LED\n\t\t\t\t\t\t\t\t\t\t// TODO implement I2C protocol to talk to temperature sensor chip (TMP101?)\n\t\t\t\t\t\t\t\t\t\t// and drive FAN speed control output.\n\n\tinput [3:0]dip;\n\twire reset, nonce_chip;\n\tassign reset = dip[0];\t\t\t// Not used\n\tassign nonce_chip = dip[1];\t\t// Distinguishes between the two Icarus FPGA's\n\n\t// Work distribution is simply copying to all miners, so no logic\n\t// needed there, simply copy the RxD.\n\tinput\tRxD;\n\toutput\tTxD;\n\n\t// Results from the input buffers (in serial_hub.v) of each slave\n\twire [SLAVES*32-1:0]\tslave_nonces;\n\twire [SLAVES*32-1:0]\tslave_debug_sr;\n\twire [SLAVES-1:0]\t\tnew_nonces;\n\n\t// Using the same transmission code as individual miners from serial.v\n\twire\t\tserial_send;\n\twire\t\tserial_busy;\n\twire [31:0]\tgolden_nonce;\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) sertx (.clk(uart_clk), .TxD(TxD), .send(serial_send), .busy(serial_busy), .word(golden_nonce));\n\n\thub_core #(.SLAVES(SLAVES)) hc (.uart_clk(uart_clk), .new_nonces(new_nonces), .golden_nonce(golden_nonce), .serial_send(serial_send), .serial_busy(serial_busy), .slave_nonces(slave_nonces));\n\n\t// Common workdata input for local miners\n\twire [255:0]\tdata1, data2;\n\twire [127:0]\tdata3;\n\twire [31:0]\t\ttarget;\n\treg  [31:0]\t\ttargetreg = 32'h000007ff;\t// Start at sane value (overwritten by serial_receive)\n\twire\t\t\trx_done;\t\t// Signals hashcore to reset the nonce\n\t\t\t\t\t\t\t\t\t// NB in my implementation, it loads the nonce from data3 which should be fine as\n\t\t\t\t\t\t\t\t\t// this should be zero, but also supports testing using non-zero nonces.\n\n\t// Synchronise across clock domains from uart_clk to hash_clk\n\t// This probably looks amateurish (mea maxima culpa, novice verilogger at work), but should be OK\n\treg rx_done_toggle = 1'b0;\t\t// uart_clk domain\n\talways @ (posedge uart_clk)\n\t\trx_done_toggle <= rx_done_toggle ^ rx_done;\n\n\treg rx_done_toggle_d1 = 1'b0;\t// hash_clk domain\n\treg rx_done_toggle_d2 = 1'b0;\n\treg rx_done_toggle_d3 = 1'b0;\n\t\n\twire loadnonce;\n\tassign loadnonce = rx_done_toggle_d3 ^ rx_done_toggle_d2;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\trx_done_toggle_d1 <= rx_done_toggle;\n\t\trx_done_toggle_d2 <= rx_done_toggle_d1;\n\t\trx_done_toggle_d3 <= rx_done_toggle_d2;\n\t\tif (loadnonce)\n\t\t\ttargetreg <= target;\n\tend\n\t// End of clock domain sync\n\n\twire [31:0] mod_target;\n\n`ifdef USE_DYN_PLL\n\t// Top byte of target is clock multiplier, 2nd byte is validation (one's complement of clock multiplier)\n\t// These bytes are always zero in normal getwork, so we now hard code in mod_target and use them to set clock speed.\n\t// NB The pll controller is in uart_clk domain so use serial_receive signals directly\n\t// wire [7:0]invtarg;\t\t\t\t\t// Just checking the syntax in simulator, DELETE\n\t// assign invtarg = ~target[24:16];\n\talways @ (posedge uart_clk)\n\tbegin\n\t\tdyn_pll_start <= 0;\n\t\t// A sanity check to reduce the risk of speed being set to garbage\n\t\t// Top byte of target is speed, second byte MUST be its inverse, and neither must be zero (which also rules out all ones)\n\t\tif (rx_done && target[31:24] != dyn_pll_speed && target[31:24] != 0 && target[23:16] != 0 && target[31:24] == ~target[23:16])\n\t\t// if (rx_done && target[31:24] != dyn_pll_speed && target[31:24] != 0)\t// Simpler version for DEBUG, does no verification\n\t\tbegin\n\t\t\tdyn_pll_speed <= target[31:24];\n\t\t\tdyn_pll_start <= 1;\n\t\tend\n\tend\n\tassign mod_target = { 16'd0, targetreg[15:0] };\t// Ignore top two bytes\n`else\n\t// Its better to always hard-wire the 16 MSB to zero ... if comms noise sets these bits it completely de-syncs,\n\t// generating a continuous stream of golden_nonces overwhelming the python driver which can't then reset the target.\n\t// assign mod_target = targetreg;\t\t\t\t// Original 32 bit target\n\tassign mod_target = { 16'd0, targetreg[15:0] };\t// Ignore top two bytes\n`endif\n\t\n\tserial_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) serrx (.clk(uart_clk), .RxD(RxD), .data1(data1),\n\t\t\t\t\t\t.data2(data2), .data3(data3), .target(target), .rx_done(rx_done));\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\n\t// Local miners now directly connected\n\tgenerate\n\t\tgenvar i;\n\t\tfor (i = 0; i < LOCAL_MINERS; i = i + 1)\n\t\t// begin: for_local_miners ... too verbose, so...\n\t\tbegin: miners\n\t\t\twire [31:0] nonce_out;\t// Not used\n\t\t\twire [2:0] nonce_core = i;\n\t\t\twire gn_match;\n\t\t\twire salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift;\n\t\t\twire [SBITS-1:0] salsa_din;\n\t\t\twire [SBITS-1:0] salsa_dout;\n\t\t\twire [3:0] dummy;\t// So we can ignore top 4 bits of slave_debug_sr\n\n\t\t\t// Currently one pbkdfengine per salsaengine - TODO share the pbkdfengine for several salsaengines\n\t\t\tpbkdfengine #(.SBITS(SBITS)) P\n\t\t\t\t(.hash_clk(hash_clk), .pbkdf_clk(pbkdf_clk), .data1(data1), .data2(data2), .data3(data3), .target(mod_target),\n\t\t\t\t.nonce_msb({nonce_chip, nonce_core}), .nonce_out(nonce_out), .golden_nonce_out(slave_nonces[i*32+31:i*32]),\n\t\t\t\t.golden_nonce_match(gn_match), .loadnonce(loadnonce),\n\t\t\t\t.salsa_din(salsa_din), .salsa_dout(salsa_dout), .salsa_busy(salsa_busy), .salsa_result(salsa_result),\n\t\t\t\t.salsa_reset(salsa_reset), .salsa_start(salsa_start), .salsa_shift(salsa_shift));\n\n\t\t\tsalsaengine #(.ADDRBITS(ADDRBITS), .SBITS(SBITS)) S\n\t\t\t\t(.hash_clk(hash_clk), .reset(salsa_reset), .din(salsa_din), .dout(salsa_dout),\n\t\t\t\t.shift(salsa_shift), .start(salsa_start), .busy(salsa_busy), .result(salsa_result) );\n\t\t\t\t\t\n\t\t\t// Synchronise across clock domains from pbkdf_clk to uart_clk for: assign new_nonces[i] = gn_match;\n\t\t\treg gn_match_toggle = 1'b0;\t\t// hash_clk domain\n\t\t\talways @ (posedge pbkdf_clk)\n\t\t\t\tgn_match_toggle <= gn_match_toggle ^ gn_match;\n\n\t\t\treg gn_match_toggle_d1 = 1'b0;\t// uart_clk domain\n\t\t\treg gn_match_toggle_d2 = 1'b0;\n\t\t\treg gn_match_toggle_d3 = 1'b0;\n\n\t\t\tassign new_nonces[i] = gn_match_toggle_d3 ^ gn_match_toggle_d2;\n\n\t\t\talways @ (posedge uart_clk)\n\t\t\tbegin\n\t\t\t\tgn_match_toggle_d1 <= gn_match_toggle;\n\t\t\t\tgn_match_toggle_d2 <= gn_match_toggle_d1;\n\t\t\t\tgn_match_toggle_d3 <= gn_match_toggle_d2;\n\t\t\tend\n\t\t\t// End of clock domain sync\n\t\tend // for\n\tendgenerate\n\n\t// External miner ports, results appended to the same\n\t// slave_nonces/new_nonces as local ones\n\toutput [EXT_PORTS-1:0] extminer_txd;\n\tinput [EXT_PORTS-1:0]  extminer_rxd;\n\t// wire [EXT_PORTS-1:0]  extminer_rxd_debug = 1'b1;\t// DISABLE INPUT\n\tassign extminer_txd = {EXT_PORTS{RxD}};\n\n\tgenerate\n\t\tgenvar j;\n\t\tfor (j = LOCAL_MINERS; j < SLAVES; j = j + 1)\n\t\t// begin: for_ports ... too verbose, so ...\n\t\tbegin: ports\n\t\t\tslave_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) slrx (.clk(uart_clk), .RxD(extminer_rxd[j-LOCAL_MINERS]), .nonce(slave_nonces[j*32+31:j*32]), .new_nonce(new_nonces[j]));\n\t\tend\n\tendgenerate\n\n\toutput [3:0] led;\n\tassign led[1] = ~RxD;\n\t// assign led[2] = ~TxD;\n\t// assign led[3] = ~ (TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED - held low (the TMP pins are PULLUP, this is a fudge to\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// avoid warning about unused inputs)\n\t\n\tassign led[3] = ~first_dcm_locked | ~dcm_locked | dcm_status[2] | ~(TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED now dcm status\n\n`define FLASHCLOCK\t\t// Gives some feedback as the the actual clock speed\n\n`ifdef FLASHCLOCK\n\treg [26:0] hash_count = 0;\n\treg [3:0] sync_hash_count = 0;\n\talways @ (posedge uart_clk)\n\t\tif (rx_done)\n\t\t\tsync_hash_count[0] <= ~sync_hash_count[0];\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tsync_hash_count[3:1] <= sync_hash_count[2:0];\n\t\thash_count <= hash_count + 1'b1;\n\t\tif (sync_hash_count[3] != sync_hash_count[2])\n\t\t\thash_count <= 0;\n\tend\n\tassign led[2] = hash_count[26];\n`else\n\tassign led[2] = ~TxD;\n`endif\n\n\t// Light up only from locally found nonces, not ext_port results\n\tpwm_fade pf (.clk(uart_clk), .trigger(|new_nonces[LOCAL_MINERS-1:0]), .drive(led[0]));\n   \nendmodule\n"
  },
  {
    "path": "ICARUS-LX150/pbkdfengine.v",
    "content": "/* pbkdfengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`define ICARUS\t\t\t// Comment this out when using the altera virtual_wire interface in ltcminer.v\n\t\n`timescale 1ns/1ps\n\nmodule pbkdfengine\n\t(hash_clk, pbkdf_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce,\n\t\t\tsalsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift);\n\n\tinput hash_clk;\t\t\t// Just drives shift register\n\tinput pbkdf_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\n\toutput [31:0] nonce_out;\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] salsa_dout;\n\toutput [SBITS-1:0] salsa_din;\n\n\tinput salsa_busy, salsa_result;\t// NB hash_clk domain\n\toutput salsa_reset;\n\toutput salsa_start;\n\toutput reg salsa_shift = 1'b0;\t// NB hash_clk domain\n\n\treg [4:0]resetcycles = 4'd0;\n\treg reset = 1'b0;\n\tassign salsa_reset = reset;\t\t// Propagate reset to salsaengine\n\n`ifdef WANTCYCLICRESET\t\t\n\treg [23:0]cycresetcount = 24'd0;\n`endif\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\t// Hard code a 31 cycle reset (NB assumes THREADS=16 in salsaengine, else we need more)\n\t\t// NB hash_clk is faster than pbkdf_clk so the salsaengine will actually be initialised well before\n\t\t// this period ends, but keep to 15 for now as simulation uses equal pbkdf and salsa clock speeds.\n\t\tresetcycles <= resetcycles + 1'd1;\n\t\tif (resetcycles == 0)\n\t\t\treset <= 1'b1;\n\t\tif (resetcycles == 31)\n\t\tbegin\n\t\t\treset <= 1'b0;\n\t\t\tresetcycles <= 31;\n\t\tend\n`ifdef WANTCYCLICRESET\t\t\n\t\t// Cyclical reset every 2_500_000 clocks to ensure salsa pipeline does not drift out of sync\n\t\t// This may be unneccessary if we reset every loadnonce\n\t\t// Actually it seems to do more harm than good, so disabled\n\t\tcycresetcount <= cycresetcount + 1'd1;\n\t\tif (cycresetcount == 2_500_000)\t// 10 per second at 25MHz (adjust as neccessary)\n\t\tbegin\n\t\t\tcycresetcount <= 24'd0;\n\t\t\tresetcycles <= 5'd0;\n\t\tend\n`endif\t\t\n\t\t// Reset on loadnonce (the hash results will be junk anyway since data changes, so no loss of shares)\n\t\tif (loadnonce)\n\t\t\tresetcycles <= 5'd0;\n\tend\n\t\n\t`ifndef ICARUS\n\treg [31:0] nonce_previous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\t`endif\n\n\t`ifndef NOMULTICORE\n\t`ifdef SIM\n\t\treg [27:0] nonce_cnt = 28'h318f;\t// Start point for simulation (NB also define SIM in serial.v)\n\t`else\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t`endif\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\tassign nonce_out = nonce;\n\n\treg [31:0] nonce_sr = 32'd0;\t\t// Nonce is shifted to salsaengine for storage/retrieval (hash_clk domain)\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\treg [2:0] nonce_wait = 3'd0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [2:0] blockcnt = 3'd0;\t\t// Takes values 1..5 for block iteration\n\treg [1023:0] Xbuf = 1024'd0;\t// Shared input/output buffer and shift register (hash_clk domain)\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\tassign salsa_din = Xbuf[1023:1024-SBITS];\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\t\n\t// MixOut is little-endian word format to match scrypt.c so convert back to big-endian\n\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] mix;\n\t\tassign mix = Xbuf[`IDX(i)];\t\t// NB MixOut now shares Xbuf since shifted in/out\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\n\t// Interface control. This should be OK provided the threads remain evenly spaced (hence we reset on loadnonce)\n\t\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\treg Clr_SMixOutRdy = 1'b0;\n\twire Clr_SMixInRdy;\n\twire Set_SMixOutRdy;\n\n\treg [4:0]salsa_busy_d = 0;\t\t\t// Sync to pbkdf_clk domain\n\treg [4:0]salsa_result_d = 0;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\t// Sync to pbkdf_clk domain\n\t\tsalsa_busy_d[0] <= salsa_busy;\n\t\tif (salsa_busy & ~ salsa_busy_d[0])\n\t\t\tsalsa_busy_d[1] <= ~ salsa_busy_d[1];\t\t// Toggle on busy going high\n\t\t\n\t\tsalsa_result_d[0] <= salsa_result;\n\t\tif (salsa_result & ~ salsa_result_d[0])\n\t\t\tsalsa_result_d[1] <= ~ salsa_result_d[1];\t// Toggle on result going high\n\tend\n\t\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tsalsa_busy_d[4:2] <= salsa_busy_d[3:1];\n\t\tsalsa_result_d[4:2] <= salsa_result_d[3:1];\n\t\t\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\t\t\t\n\t\t// CARE there is a race with Set_SMixInRdy, Clr_SMixOutRdy which are set in the FSM\n\t\t// Need to assert reset for several cycles to ensure consistency (acutally use 15 since salsaengine needs more)\n\t\tif (reset)\n\t\tbegin\t\t\t\t\t\t\t// Reset takes priority\n\t\t\tSMixInRdy_state <= 1'b0;\n\t\t\tSMixOutRdy_state <= 1'b0;\n\t\tend\n\tend\n\t\n\tassign Clr_SMixInRdy = SMixInRdy_state & (salsa_busy_d[3] ^ salsa_busy_d[4]);\t\t\t// Clear on transition to busy\n\t\n\tassign Set_SMixOutRdy = ~SMixOutRdy_state & (salsa_result_d[3] ^ salsa_result_d[4]);\t// Set on transition to result\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\tassign salsa_start = SMixInRdy;\n\t\t\n\t// Clock crossing flags for shift register control (span pbkdf_clk, hash_clk domains)\n\treg [3:0]Xbuf_load_request = 1'b0;\n\treg [3:0]shift_request =  1'b0;\n\treg [3:0]shift_acknowledge = 1'b0;\n\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz)\n\t\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_NONCE=22, S_SHIFT_IN=41, S_SHIFT_OUT=42,\t\t\t\t// Direction relative to salsa unit\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\treg start_output = 0;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\n\t\tshift_acknowledge[3:1] <= shift_acknowledge[2:0];\t// Clock crossing\n\n\t\t`ifdef ICARUS\n\t\tif (loadnonce)\t\t\t\t// Separate clock domains means comparison is unsafe\n\t\t`else\n\t\tif (loadnonce || (nonce_previous_load != data3[127:96]))\n\t\t`endif\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_previous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\t`ifndef ICARUS\n\t\t\tnonce_previous_load <= data3[127:96];\n\t\t\t`endif\n\t\tend\n\t\t\n\t\tif (reset == 1'b1)\n\t\tbegin\n\t\t\tstate <= S_IDLE;\n\t\t\tstart_output <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tif (SMixOutRdy & ~start_output)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\t// Request shifter to start\n\t\t\t\t\t\tstate <= S_SHIFT_OUT;\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (start_output ||\t// Process output\n\t\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'b0;\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\t\tblockcnt <= 3'd1;\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_sr : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\t\t\n\t\t\t\tS_B6: begin\n\t\t\t\t\t\tkhash <= tx_hash;\t\t// Save temporarily (for Xbuf)\n\n\t\t\t\t\t\tXbuf_load_request[0] <= ~Xbuf_load_request[0];\t// NB also loads nonce_sr\n\n\t\t\t\t\t\tif (blockcnt == 3'd5)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tnonce_wait <= 3'd7;\n\t\t\t\t\t\t\tstate <= S_NONCE;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_NONCE: begin\n\t\t\t\t\t\t// Need to delay a few clocks for Xbuf_load_request to complete\n\t\t\t\t\t\tnonce_wait <= nonce_wait - 1'd1;\n\t\t\t\t\t\tif (nonce_wait == 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 1'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 1'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\n\t\t\t\t\t\t\tstate <= S_SHIFT_IN;\n\t\t\t\t\t\tend\n\t\t\t\t\n\t\t\t\tend\n\t\t\t\tS_SHIFT_IN: begin\t\t\t\t\t\t\t// Shifting from PBKDF2_SHA256 to salsa\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tSet_SMixInRdy <= 1'd1;\t\t\t\t// Flag salsa to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_SHIFT_OUT: begin\t\t\t\t\t\t\t// Shifting from salsa to PBKDF2_SHA256\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'd1;\t\t\t\t// Flag self to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_sr;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n\tend\n\n\t// Shift register control - NB hash_clk domain\n\t\n\treg\t[10:0]shift_count = 11'd0;\t// hash_clk domain\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tif (reset)\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b0;\n\t\t\tshift_count <= 11'd0;\n\t\tend\n\n\t\t// Clock crossing logic\n\t\tXbuf_load_request[3:1] <= Xbuf_load_request[2:0];\n\t\tif (Xbuf_load_request[3] != Xbuf_load_request[2])\n\t\tbegin\n\t\t\t// Shift output into X buffer from MSB->LSB\n\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\tXbuf[1023:768] <= khash;\n\n\t\t\tnonce_sr <= nonce;\t// Loaded several times, but of no consequence\n\t\tend\n\t\t\n\t\tshift_request[3:1] <= shift_request[2:0];\n\t\tif (shift_request[3] != shift_request[2])\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b1;\n\t\tend\n\n\t\tif (salsa_shift)\n\t\tbegin\n\t\t\tshift_count <= shift_count + 1'b1;\n\t\t\tXbuf <= { Xbuf[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], salsa_dout };\n\t\tend\n\t\t\n\t\tif (shift_count == (1024+32)/SBITS-1)\n\t\tbegin\n\t\t\tshift_acknowledge[0] = ~shift_acknowledge[0];\n\t\t\tshift_count <= 0;\n\t\t\tsalsa_shift <= 0;\n\t\tend\n\tend\n\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(pbkdf_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\nendmodule"
  },
  {
    "path": "ICARUS-LX150/pwm_fade.v",
    "content": "// When triggered, turn the output to maximum and start fading to black\n\n// by teknohog\n\nmodule pwm_fade (clk, trigger, drive);\n   input trigger;\n   input clk;\n   output drive;\n\n   `define FADE_BITS 27\n   parameter LEVEL_BITS = 8;\n\n   // Average block interval in clock cycles is\n   // 2**32 / (clk * 0.5**ll2 * miners) * clk\n   // where (clk * 0.5**ll2 * miners) is the hashrate\n   parameter LOCAL_MINERS = 1;\n   //parameter LOOP_LOG2 = 5;\n   //localparam FADE_BITS = 32 + LOOP_LOG2 - $clog2(LOCAL_MINERS);\n\n   // Xilinx ISE 13.2 cannot handle $clog2 in localparam, but it works\n   // in the index\n   //`define FADE_BITS (32 + LOOP_LOG2 - $clog2(LOCAL_MINERS))\n   \n   reg [LEVEL_BITS-1:0] pwm_counter = 0;\n   always @(posedge clk) pwm_counter = pwm_counter + 1;\n\n   reg [`FADE_BITS-1:0] fade_counter = 0;\n   always @(posedge clk)\n     if (trigger) fade_counter = 0 - 1;\n     else if (|fade_counter) fade_counter = fade_counter - 1;\n   \n   // For some reason, {FADE_BITS{1}} sets the register to zero, but\n   // 0-1 works. Also, it needs to be explicitly initialized to\n   // zero. Could be just a Nexys2 quirk, as these LEDs are routed to\n   // general I/O pins too.\n     \n   wire [LEVEL_BITS-1:0] level;\n   assign level = fade_counter[`FADE_BITS-1:`FADE_BITS-LEVEL_BITS];\n\n   // With <= we cannot have true zero; with < we cannot have full\n   // brightness. This is a rather fundamental problem, since we need\n   // 256 timeslices to fill the whole, but the choice of \"off\" would\n   // require an extra bit... of course, it is possible to get by\n   // using a little extra logic.\n   assign drive = (pwm_counter < level);\n   \nendmodule\n"
  },
  {
    "path": "ICARUS-LX150/salsa_slowsixteen.v",
    "content": "/* salsa_slowsixteen.v\n*\n* Copyright (c) 2013 kramble\n* Derived from scrypt.c Copyright 2009 Colin Percival, 2011 ArtForz\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\nmodule salsa (clk, B, Bx, Bo, X0out, Xaddr);\n\n// Latency 16 clock cycles, approx 20nS propagation delay (SLOW!)\n\ninput clk;\n// input feedback;\ninput [511:0]B;\ninput [511:0]Bx;\n// output reg [511:0]Bo;\t// Output is registered\noutput [511:0]Bo;\t\t\t// Output is async\noutput [511:0]X0out;\t\t// Becomes new X0\noutput [9:0] Xaddr;\nwire [9:0] xa1, xa2, xa3, xa4, ya1, ya2, ya3, ya4;\n\nreg [511:0]x1d1, x1d1a;\nreg [511:0]x1d2, x1d2a;\nreg [511:0]x1d3, x1d3a;\nreg [511:0]x1d4, x1d4a;\n\nreg [511:0]Xod1, Xod1a;\nreg [511:0]Xod2, Xod2a;\nreg [511:0]Xod3, Xod3a;\nreg [511:0]Xod4, X0out;\n\nreg [511:0]xxd1, xxd1a;\nreg [511:0]xxd2, xxd2a;\nreg [511:0]xxd3, xxd3a;\nreg [511:0]xxd4, xxd4a;\n\nreg [511:0]yyd1, yyd1a;\nreg [511:0]yyd2, yyd2a;\nreg [511:0]yyd3, yyd3a;\nreg [511:0]yyd4, yyd4a;\n\nwire [511:0]xx;\t\t\t// Initial xor\nwire [511:0]x1;\t\t\t// Salasa core outputs\nwire [511:0]x2;\nwire [511:0]x3;\nwire [511:0]xr;\nwire [511:0]Xo;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsax1 (clk, xx, x1, xa1);\nsalsa_core salsax2 (clk, x1, x2, xa2);\nsalsa_core salsax3 (clk, x2, x3, xa3);\nsalsa_core salsax4 (clk, x3, xr, xa4);\n\nwire [511:0]yy;\t\t\t// Initial xor\nwire [511:0]y1;\t\t\t// Salasa core outputs\nwire [511:0]y2;\nwire [511:0]y3;\nwire [511:0]yr;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsay1 (clk, yy, y1, ya1);\nsalsa_core salsay2 (clk, y1, y2, ya2);\nsalsa_core salsay3 (clk, y2, y3, ya3);\nsalsa_core salsay4 (clk, y3, yr, ya4);\n\nassign Xaddr = yyd4[9:0] + ya4;\n\ngenvar i;\ngenerate\n\tfor (i = 0; i < 16; i = i + 1) begin : XX\n\t\t// Initial XOR. NB this adds to the propagation delay of the first salsa, may want register it.\n\t\tassign xx[`IDX(i)] = B[`IDX(i)] ^ Bx[`IDX(i)];\n\t\tassign Xo[`IDX(i)] = xxd4a[`IDX(i)] + xr[`IDX(i)];\n\t\tassign yy[`IDX(i)] = x1d4a[`IDX(i)] ^ Xo[`IDX(i)];\n\t\tassign Bo[`IDX(i)] = yyd4a[`IDX(i)] + yr[`IDX(i)];\t// Async output\n\tend\nendgenerate\n\nalways @ (posedge clk)\nbegin\n\tx1d1 <= Bx;\n\tx1d1a <= x1d1;\n\tx1d2 <= x1d1a;\n\tx1d2a <= x1d2;\n\tx1d3 <= x1d2a;\n\tx1d3a <= x1d3;\n\tx1d4 <= x1d3a;\n\tx1d4a <= x1d4;\n\tXod1 <= Xo;\n\tXod1a <= Xod1;\n\tXod2 <= Xod1a;\n\tXod2a <= Xod2;\n\tXod3 <= Xod2a;\n\tXod3a <= Xod3;\n\tXod4 <= Xod3a;\n\tX0out <= Xod4;\t// We output this to become new X0\n\n\txxd1 <= xx;\n\txxd1a <= xxd1;\n\txxd2 <= xxd1a;\n\txxd2a <= xxd2;\n\txxd3 <= xxd2a;\n\txxd3a <= xxd3;\n\txxd4 <= xxd3a;\n\txxd4a <= xxd4;\n\n\tyyd1 <= yy;\n\tyyd1a <= yyd1;\n\tyyd2 <= yyd1a;\n\tyyd2a <= yyd2;\n\tyyd3 <= yyd2a;\n\tyyd3a <= yyd3;\n\tyyd4 <= yyd3a;\n\tyyd4a <= yyd4;\n\nend\n\nendmodule\n\nmodule salsa_core (clk, xx, out, Xaddr);\n\ninput clk;\ninput [511:0]xx;\noutput reg [511:0]out;\t\t// Output is registered\noutput [9:0] Xaddr;\t\t\t// Address output unregistered\n\n// This is clunky due to my lack of verilog skills but it works so elegance can come later\n\nwire [31:0]c00;\t\t\t// Column results\nwire [31:0]c01;\nwire [31:0]c02;\nwire [31:0]c03;\nwire [31:0]c04;\nwire [31:0]c05;\nwire [31:0]c06;\nwire [31:0]c07;\nwire [31:0]c08;\nwire [31:0]c09;\nwire [31:0]c10;\nwire [31:0]c11;\nwire [31:0]c12;\nwire [31:0]c13;\nwire [31:0]c14;\nwire [31:0]c15;\n\nwire [31:0]r00;\t\t\t// Row results\nwire [31:0]r01;\nwire [31:0]r02;\nwire [31:0]r03;\nwire [31:0]r04;\nwire [31:0]r05;\nwire [31:0]r06;\nwire [31:0]r07;\nwire [31:0]r08;\nwire [31:0]r09;\nwire [31:0]r10;\nwire [31:0]r11;\nwire [31:0]r12;\nwire [31:0]r13;\nwire [31:0]r14;\nwire [31:0]r15;\n\nwire [31:0]c00s;\t\t\t// Column sums\nwire [31:0]c01s;\nwire [31:0]c02s;\nwire [31:0]c03s;\nwire [31:0]c04s;\nwire [31:0]c05s;\nwire [31:0]c06s;\nwire [31:0]c07s;\nwire [31:0]c08s;\nwire [31:0]c09s;\nwire [31:0]c10s;\nwire [31:0]c11s;\nwire [31:0]c12s;\nwire [31:0]c13s;\nwire [31:0]c14s;\nwire [31:0]c15s;\n\nwire [31:0]r00s;\t\t\t// Row sums\nwire [31:0]r01s;\nwire [31:0]r02s;\nwire [31:0]r03s;\nwire [31:0]r04s;\nwire [31:0]r05s;\nwire [31:0]r06s;\nwire [31:0]r07s;\nwire [31:0]r08s;\nwire [31:0]r09s;\nwire [31:0]r10s;\nwire [31:0]r11s;\nwire [31:0]r12s;\nwire [31:0]r13s;\nwire [31:0]r14s;\nwire [31:0]r15s;\n\nreg [31:0]c00d;\t\t\t// Column results registered\nreg [31:0]c01d;\nreg [31:0]c02d;\nreg [31:0]c03d;\nreg [31:0]c04d;\nreg [31:0]c05d;\nreg [31:0]c06d;\nreg [31:0]c07d;\nreg [31:0]c08d;\nreg [31:0]c09d;\nreg [31:0]c10d;\nreg [31:0]c11d;\nreg [31:0]c12d;\nreg [31:0]c13d;\nreg [31:0]c14d;\nreg [31:0]c15d;\n\n/* From scrypt.c\n\n#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))\n\tfor (i = 0; i < 8; i += 2) {\n\t\t// Operate on columns\n\t\tx04 ^= R(x00+x12, 7);\tx09 ^= R(x05+x01, 7);\tx14 ^= R(x10+x06, 7);\tx03 ^= R(x15+x11, 7);\n\t\tx08 ^= R(x04+x00, 9);\tx13 ^= R(x09+x05, 9);\tx02 ^= R(x14+x10, 9);\tx07 ^= R(x03+x15, 9);\n\t\tx12 ^= R(x08+x04,13);\tx01 ^= R(x13+x09,13);\tx06 ^= R(x02+x14,13);\tx11 ^= R(x07+x03,13);\n\t\tx00 ^= R(x12+x08,18);\tx05 ^= R(x01+x13,18);\tx10 ^= R(x06+x02,18);\tx15 ^= R(x11+x07,18);\n\n\t\t// Operate on rows\n\t\tx01 ^= R(x00+x03, 7);\tx06 ^= R(x05+x04, 7);\tx11 ^= R(x10+x09, 7);\tx12 ^= R(x15+x14, 7);\n\t\tx02 ^= R(x01+x00, 9);\tx07 ^= R(x06+x05, 9);\tx08 ^= R(x11+x10, 9);\tx13 ^= R(x12+x15, 9);\n\t\tx03 ^= R(x02+x01,13);\tx04 ^= R(x07+x06,13);\tx09 ^= R(x08+x11,13);\tx14 ^= R(x13+x12,13);\n\t\tx00 ^= R(x03+x02,18);\tx05 ^= R(x04+x07,18);\tx10 ^= R(x09+x08,18);\tx15 ^= R(x14+x13,18);\n\t}\n*/\n\n// cols\n\nassign c04s = xx[`IDX(0)] + xx[`IDX(12)];\nassign c04 = xx[`IDX(4)] ^ { c04s[24:0], c04s[31:25] };\nassign c09s = xx[`IDX(5)] + xx[`IDX(1)];\nassign c09 = xx[`IDX(9)] ^ { c09s[24:0], c09s[31:25] };\nassign c14s = xx[`IDX(10)] + xx[`IDX(6)];\nassign c14 = xx[`IDX(14)] ^ { c14s[24:0], c14s[31:25] };\nassign c03s = xx[`IDX(15)] + xx[`IDX(11)];\nassign c03 = xx[`IDX(03)] ^ { c03s[24:0], c03s[31:25] };\n\nassign c08s = c04 + xx[`IDX(0)];\nassign c08 = xx[`IDX(8)] ^ { c08s[22:0], c08s[31:23] };\nassign c13s = c09 + xx[`IDX(5)];\nassign c13 = xx[`IDX(13)] ^ { c13s[22:0], c13s[31:23] };\nassign c02s = c14 + xx[`IDX(10)];\nassign c02 = xx[`IDX(2)] ^ { c02s[22:0], c02s[31:23] };\nassign c07s = c03 + xx[`IDX(15)];\nassign c07 = xx[`IDX(7)] ^ { c07s[22:0], c07s[31:23] };\n\nassign c12s = c08 + c04;\nassign c12 = xx[`IDX(12)] ^ { c12s[18:0], c12s[31:19] };\nassign c01s = c13 + c09;\nassign c01 = xx[`IDX(1)] ^ { c01s[18:0], c01s[31:19] };\nassign c06s = c02 + c14;\nassign c06 = xx[`IDX(6)] ^ { c06s[18:0], c06s[31:19] };\nassign c11s = c07 + c03;\nassign c11 = xx[`IDX(11)] ^ { c11s[18:0], c11s[31:19] };\n\nassign c00s = c12 + c08;\nassign c00 = xx[`IDX(0)] ^ { c00s[13:0], c00s[31:14] };\nassign c05s = c01 + c13;\nassign c05 = xx[`IDX(5)] ^ { c05s[13:0], c05s[31:14] };\nassign c10s = c06 + c02;\nassign c10 = xx[`IDX(10)] ^ { c10s[13:0], c10s[31:14] };\nassign c15s = c11 + c07;\nassign c15 = xx[`IDX(15)] ^ { c15s[13:0], c15s[31:14] };\n\n// rows\n\nassign r01s = c00d + c03d;\nassign r01 = c01d ^ { r01s[24:0], r01s[31:25] };\nassign r06s = c05d + c04d;\nassign r06 = c06d ^ { r06s[24:0], r06s[31:25] };\nassign r11s = c10d + c09d;\nassign r11 = c11d ^ { r11s[24:0], r11s[31:25] };\nassign r12s = c15d + c14d;\nassign r12 = c12d ^ { r12s[24:0], r12s[31:25] };\n\nassign r02s = r01 + c00d;\nassign r02 = c02d ^ { r02s[22:0], r02s[31:23] };\nassign r07s = r06 + c05d;\nassign r07 = c07d ^ { r07s[22:0], r07s[31:23] };\nassign r08s = r11 + c10d;\nassign r08 = c08d ^ { r08s[22:0], r08s[31:23] };\nassign r13s = r12 + c15d;\nassign r13 = c13d ^ { r13s[22:0], r13s[31:23] };\n\nassign r03s = r02 + r01;\nassign r03 = c03d ^ { r03s[18:0], r03s[31:19] };\nassign r04s = r07 + r06;\nassign r04 = c04d ^ { r04s[18:0], r04s[31:19] };\nassign r09s = r08 + r11;\nassign r09 = c09d ^ { r09s[18:0], r09s[31:19] };\nassign r14s = r13 + r12;\nassign r14 = c14d ^ { r14s[18:0], r14s[31:19] };\n\nassign r00s = r03 + r02;\nassign r00 = c00d ^ { r00s[13:0], r00s[31:14] };\nassign r05s = r04 + r07;\nassign r05 = c05d ^ { r05s[13:0], r05s[31:14] };\nassign r10s = r09 + r08;\nassign r10 = c10d ^ { r10s[13:0], r10s[31:14] };\nassign r15s = r14 + r13;\nassign r15 = c15d ^ { r15s[13:0], r15s[31:14] };\n\nwire [511:0]xo;\t\t\t// Rename row results\nassign xo = { r15, r14, r13, r12, r11, r10, r09, r08, r07, r06, r05, r04, r03, r02, r01, r00 };\n\nassign Xaddr = xo[9:0];\t// Unregistered output\n\nalways @ (posedge clk)\nbegin\n\tc00d <= c00;\n\tc01d <= c01;\n\tc02d <= c02;\n\tc03d <= c03;\n\tc04d <= c04;\n\tc05d <= c05;\n\tc06d <= c06;\n\tc07d <= c07;\n\tc08d <= c08;\n\tc09d <= c09;\n\tc10d <= c10;\n\tc11d <= c11;\n\tc12d <= c12;\n\tc13d <= c13;\n\tc14d <= c14;\n\tc15d <= c15;\n\tout <= xo;\t\t// Registered output\nend\n\nendmodule\n"
  },
  {
    "path": "ICARUS-LX150/salsaengine.v",
    "content": "/* salsaengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n// NB HALFRAM no longer applies, configure via parameters ADDRBITS, THREADS\n\n// Bracket this config option in SIM so we don't accidentally leave it set in a live build\n`ifdef SIM\n//`define ONETHREAD\t// Start one thread only (for SIMULATION less confusing and faster startup)\n`endif\n\n`timescale 1ns/1ps\n\nmodule salsaengine (hash_clk, reset, din, dout, shift, start, busy, result );\n\n\n\tinput hash_clk;\n\tinput reset;\t// NB pbkdf_clk domain (need a long reset (at least THREADS+4) to initialize correctly, this is done in pbkdfengine (15 cycles)\n\tinput shift;\n\tinput start;\t// NB pbkdf_clk domain\n\toutput busy;\n\toutput reg result = 1'b0;\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] din;\n\toutput [SBITS-1:0] dout;\n\n\t// Configure ADDRBITS to allocate RAM for core (automatically sets LOOKAHEAD_GAP)\n\t// NB do not use ADDRBITS > 13 for THREADS=8 since this corresponds to more than a full scratchpad\n\n\t// These settings are now overriden in ltcminer_icarus.v determined by LOCAL_MINERS ...\n\t// parameter ADDRBITS = 13;\t// 8MBit RAM allocated to core, full scratchpad (will not fit LX150)\n\tparameter ADDRBITS = 12;\t// 4MBit RAM allocated to core, half scratchpad\n\t// parameter ADDRBITS = 11;\t// 2MBit RAM allocated to core, quarter scratchpad\n\t// parameter ADDRBITS = 10;\t// 1MBit RAM allocated to core, eighth scratchpad\n\n\t// Do not change THREADS - this must match the salsa pipeline (code is untested for other values)\n\tparameter THREADS = 16;\t\t// NB Phase has THREADS+1 cycles\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n\tparameter THREADS_BITS = clog2(THREADS);\n\t\n\t// Workaround for range-reversal error in inactive code when ADDRBITS=13\n\tparameter ADDRBITSX = (ADDRBITS == 13) ? ADDRBITS-1 : ADDRBITS;\n\n\treg [THREADS_BITS:0]phase = 0;\n\treg [THREADS_BITS:0]phase_d = THREADS+1;\n\treg reset_d=0, fsmreset=0, start_d=0, fsmstart=0;\n\n\talways @ (posedge hash_clk)\t\t// Phase control and sync\n\tbegin\n\t\tphase <= (phase == THREADS) ? 0 : phase + 1;\n\t\tphase_d <= phase;\n\t\treset_d <= reset;\t\t\t// Synchronise to hash_clk domain\n\t\tfsmreset <= reset_d;\n\t\tstart_d <= start;\n\t\tfsmstart <= start_d;\n\tend\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\tparameter XSnull = 0, XSload = 1, XSmix = 2, XSram = 4;\t\t\t// One-hot since these map directly to mux contrls\n\treg [2:0] XCtl = XSnull;\n\n\tparameter R_IDLE=0, R_START=1, R_WRITE=2, R_MIX=3, R_INT=4, R_WAIT=5;\n\treg [2:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs\n\treg addrsourceMix = 1'b0;\n\treg datasourceLoad = 1'b0;\n\treg addrsourceSave = 1'b0;\n\treg resultsourceRam = 1'b0;\n\treg xoren = 1'b1;\n\treg [THREADS_BITS+1:0] intcycles = 0;\t// Number of interpolation cycles required ... How many do we need? Say THREADS_BITS+1\n\n\twire [511:0] Xmix;\n\treg [511:0] X0;\n\treg [511:0] X1;\n\twire [511:0] X0in;\n\twire [511:0] X1in;\n\twire [511:0] X0out;\n\treg [1023:0] salsaShiftReg;\n\treg [31:0] nonce_sr;\t\t\t// In series with salsaShiftReg\n\tassign dout = salsaShiftReg[1023:1024-SBITS];\n\n\t// sstate is implemented in ram (alternatively could use a rotating shift register)\n\treg [THREADS_BITS+30:0] sstate [THREADS-1:0];\t\t// NB initialized via a long reset (see pbkdfengine)\n\t// List components of sstate here for ease of maintenance ...\n\twire [2:0] mstate_in;\n\twire [10:0] cycle_in;\n\twire [9:0] writeaddr_in;\n\twire doneROM_in;\n\twire addrsourceMix_in;\n\twire addrsourceSave_in;\n\twire [THREADS_BITS+1:0] intcycles_in;\t\t\t\t// How many do we need? Say THREADS_BITS+1\n\n\twire [9:0] writeaddr_next = writeaddr_in + 10'd1;\n\n\treg [31:0] snonce [THREADS-1:0];\t\t\t\t\t// Nonce store. Note bidirectional loading below, this will either implement\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// as registers or dual-port ram, so do NOT integrate with sstate.\n\t\n\t// NB no busy_in or result_in as these flag are NOT saved on a per-thread basis\n\n\t// Convert salsaShiftReg to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = salsaShiftReg[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\tend\n\tendgenerate\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of RAM size\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\twire [9:0] Xaddr;\n\twire [ADDRBITS-1:0]rd_addr;\n\twire [ADDRBITS-1:0]wr_addr1;\n\twire [ADDRBITS-1:0]wr_addr2;\n\twire [ADDRBITS-1:0]wr_addr3;\n\twire [ADDRBITS-1:0]wr_addr4;\n\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\t(* S = \"TRUE\" *) reg ram_wren = 1'b0;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\t// Top ram address is reserved for X0Save/X1save, so adjust\n\t\n\twire [15:0] memtop = 16'hfffe;\t// One less than the top memory location (per THREAD bank)\n\t\n\twire [ADDRBITS-THREADS_BITS-1:0] adj_addr;\n\n\tif (ADDRBITS < 13)\n\t\tassign adj_addr = (Xaddr[9:THREADS_BITS+10-ADDRBITS] == memtop[9:THREADS_BITS+10-ADDRBITS]) ?\n\t\t\t\t\t\t\tmemtop[ADDRBITS-THREADS_BITS-1:0] : Xaddr[9:THREADS_BITS+10-ADDRBITS];\n\telse\n\t\tassign adj_addr = Xaddr;\n\t\n\twire [THREADS_BITS-1:0] phase_addr;\n\tassign phase_addr = phase[THREADS_BITS-1:0];\n\n\t// TODO can we remove the +1 and adjust the wr_addr to use the same prefix via phase_d?\n\tassign rd_addr = { phase_addr+1, addrsourceSave_in ? memtop[ADDRBITS-THREADS_BITS:1] : adj_addr };\t// LSB are ignored\n\t\t\n\twire [9:0] writeaddr_adj = addrsourceMix ? memtop[10:1] : writeaddr;\n\t\n\tassign wr_addr1 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\tassign wr_addr2 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\tassign wr_addr3 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\tassign wr_addr4 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\n\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_1 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_2 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_3 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_4 = 0;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr1 = rd_addr | rd_addr_z_1;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr2 = rd_addr | rd_addr_z_2;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr3 = rd_addr | rd_addr_z_3;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr4 = rd_addr | rd_addr_z_4;\n\t\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (rd_addr1, wr_addr1, ram_clk, ram1_din, ram_wren, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (rd_addr2, wr_addr2, ram_clk, ram2_din, ram_wren, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (rd_addr3, wr_addr3, ram_clk, ram3_din, ram_wren, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (rd_addr4, wr_addr4, ram_clk, ram4_din, ram_wren, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = datasourceLoad ? X : { Xmix, X0out};\t// Registered input\n\t\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, X0, X1, Xmix, X0out, Xaddr);\n\n\t// Main multiplexer\n\twire [511:0] Zbits;\n\tassign Zbits = {512{xoren}};\t\t// xoren enables xor from ram (else we load from ram)\n\t\n\t// With luck the synthesizer will interpret this correctly as one-hot control ...\n\n\t// DEBUG using default state of 0 for XSnull so as to show up issues with preserved values (previously held value X0/X1)\n\t// assign X0in = (XCtl==XSmix) ? X0out : (XCtl==XSram) ? (X0out & Zbits) ^ ramout[511:0] : (XCtl==XSload) ? X[511:0] : 0;\n\t// assign X1in = (XCtl==XSmix) ? Xmix : (XCtl==XSram) ? (Xmix & Zbits) ^ ramout[1023:512] : (XCtl==XSload) ? X[1023:512] : 0;\n\t\n\t// Now using explicit control signals (rather than relying on synthesizer to map correctly)\n\t// XSMix is now the default (XSnull is unused as this mapped onto zero in the DEBUG version above) - TODO amend FSM accordingly\n\tassign X0in =  XCtl[2] ? (X0out & Zbits) ^ ramout[511:0] : XCtl[0] ? X[511:0] : X0out;\n\tassign X1in =  XCtl[2] ? (Xmix & Zbits) ^ ramout[1023:512] : XCtl[0] ? X[1023:512] : Xmix;\n\n\t// Salsa FSM - TODO may want to move this into a separate function (for floorplanning), see hashvariant-C\n\n\t// Hold separate state for each thread (a bit of a kludge to avoid rewriting FSM from scratch)\n\t// NB must ensure shift and result do NOT overlap by carefully controlling timing of start signal\n\t// NB Phase has THREADS+1 cycles, but we do not save the state for (phase==THREADS) as it is never active\n\n\tassign { mstate_in, writeaddr_in, cycle_in, doneROM_in, addrsourceMix_in, addrsourceSave_in, intcycles_in} =\n\t\t\t\t(phase == THREADS ) ? 0 : sstate[phase];\t\n\t\n\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\n\treg busy_flag = 1'b0;\n\t\n`ifdef ONETHREAD\n\t// TEST CONTROLLER ... just allow a single thread to run (busy is currently a common flag)\n\t// NB the thread automatically restarts after it completes, so its a slight misnomer to say it starts once.\n\treg start_once = 1'b0;\n\twire start_flag;\n\tassign start_flag = fsmstart & ~start_once;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine\n`else\n\t// NB start_flag only has effect when a thread is at R_IDLE, ie after reset, normally a thread will automatically\n\t// restart on completion. We need to spread the R_IDLE starts evenly to ensure proper ooperation. NB the pbkdf\n\t// engine requires busy and result, but this  looks alter itself in the salsa FSM, even though these are global\n\t// flags. Reset periodically (on loadnonce in pbkdfengine) to ensure it stays in sync.\n\treg [15:0] start_count = 0;\n\t// TODO automatic configuration (currently assumes THREADS 8 or 16, and ADDRBITS 12,11,10 calculated as follows...)\n\t// For THREADS=8, lookup_gap=2 salsa takes on average 9*(1024+(1024*1.5)) = 23040 clocks, generically 9*1024*(lookup_gap/2+1.5)\n\t// For THREADS=16, use 17*1024*(lookup_gap/2+1.5), where lookupgap is double that for THREADS=8\n\tparameter START_INTERVAL = (THREADS==16) ?\t((ADDRBITS==12) ? 60928 : (ADDRBITS==11) ? 95744 : 165376) / THREADS :\t// 16 threads\n\t\t\t\t\t\t\t\t\t\t\t\t((ADDRBITS==12) ? 23040 : (ADDRBITS==11) ? 36864 :  50688) / THREADS ;\t//  8 threads\n\treg start_flag = 1'b0;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine - this will toggle on transtion through R_START\n`endif\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tX0 <= X0in;\n\t\tX1 <= X1in;\n\t\t\n\t\tif (phase_d != THREADS)\n\t\t\tsstate[phase_d] <= fsmreset ? 0 : { mstate, writeaddr, cycle, doneROM, addrsourceMix, addrsourceSave, intcycles };\n\n\t\tmstate <= mstate_in;\t\t// Set defaults (overridden below as necessary)\n\t\twriteaddr <= writeaddr_in;\n\t\tcycle <= cycle_in;\n\t\tintcycles <= intcycles_in;\n\t\tdoneROM <= doneROM_in;\n\t\taddrsourceMix <= addrsourceMix_in;\n\t\taddrsourceSave <= addrsourceSave_in;\t\t// Overwritten below, but addrsourceSave_in is used above\n\t\t\n\t\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\trd_addr_z_1 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_2 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_3 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_4 <= {ADDRBITS{fsmreset}};\n\t\t\n\t\tXCtl <= XSnull;\t\t\t\t// Default states\n\t\taddrsourceSave <= 0;\t\t// NB addrsourceSave_in is the active control so this DOES need to be in sstate\n\t\tdatasourceLoad <= 0;\t\t// Does not need to be saved in sstate\n\t\tresultsourceRam <= 0;\t\t// Does not need to be saved in sstate\n\t\tram_wren <= 0;\n\t\txoren <= 1;\n\t\t\n\t\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\t\t`ifdef ONETHREAD\n\t\tif (fsmstart && phase!=THREADS)\n\t\t\tstart_once <= 1'b1;\n\t\tif (fsmreset)\n\t\t\tstart_once <= 1'b0;\n\t\t`else\n\t\tstart_count <= start_count + 1;\n\t\t// start_flag <= 1'b0;\t\t\t// Done below when we transition out of R_IDLE\n\t\tif (fsmreset || start_count == START_INTERVAL)\n\t\tbegin\n\t\t\tstart_count <= 0;\n\t\t\tif (~fsmreset && fsmstart)\n\t\t\t\tstart_flag <= 1'b1;\n\t\tend\n\t\t`endif\n\t\t\n\t\t// Could use explicit mux for this ...\n\t\tif (shift)\n\t\tbegin\n\t\t\tsalsaShiftReg <= { salsaShiftReg[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], din};\n\t\tend\n\t\telse\n\t\tif (XCtl==XSload && phase_d != THREADS)\t\t// Set at end of previous hash - this is executed regardless of phase\t\t\n\t\tbegin\n\t\t\tsalsaShiftReg <= resultsourceRam ? ramout : { Xmix, X0out };\t// Simultaneously with XSload\n\t\t\tnonce_sr <= snonce[phase_d];\t\t\t\t\t\t\t\t\t// NB bidirectional load\n\t\t\tsnonce[phase_d] <= nonce_sr;\n\t\tend\n\t\t\n\t\tif (fsmreset == 1'b1)\n\t\tbegin\n\t\t\tmstate <= R_IDLE;\t\t// This will propagate to all sstate slots as we hold reset for 10 cycles\n\t\t\tbusy_flag <= 1'b0;\n\t\t\tresult <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate_in)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\t// R_IDLE only applies after reset. Normally each thread will reenter at S_START and\n\t\t\t\t\t// assumes that input data is waiting (this relies on the threads being started evenly,\n\t\t\t\t\t// hence the interface FSM at the top of this file)\n\t\t\t\t\tif (phase!=THREADS && start_flag)\t// Ensure (phase==THREADS) slot is never active\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSload;\t\t\t// First time only (normally done at end of previous salsa cycle=1023)\n\t\t\t\t\t\t`ifndef ONETHREAD\n\t\t\t\t\t\t\tstart_flag <= 1'b0;\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t\t// Toggle the busy flag low to ack pbkdfengine (its usually already set\n\t\t\t\t\t\t\t\t\t\t\t\t// since other threads are running)\n\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\tdatasourceLoad <= 1'b1;\n\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tmstate <= R_START;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_START: begin\t\t\t\t\t\t// Reentry point after thread completion. ASSUMES new data is ready.\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\t\twriteaddr <= writeaddr_next;\n\t\t\t\t\t\tcycle <= 0;\n\t\t\t\t\t\tif (ADDRBITS == 13)\n\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Full scratchpad needs to write to addr=001 next cycle\n\t\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\t\tbusy_flag <= 1'b1;\n\t\t\t\t\t\tresult <= 1'b0;\n\t\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\t\tend\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\twriteaddr <= writeaddr_next;\n\t\t\t\t\tif (writeaddr_in==1022)\n\t\t\t\t\t\tdoneROM <= 1'b1;\t\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\telse\n\t\t\t\t\tif (~doneROM_in)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\t\tram_wren <= ~|writeaddr_next[THREADS_BITS+9-ADDRBITSX:0];\t// Only write non-interpolated addresses\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\tend\n\t\t\t\t\t\n\t\t\t\t\tif (doneROM_in)\n\t\t\t\t\tbegin\n\t\t\t\t\t\taddrsourceMix <= 1'b1;\t\t// Remains set for duration of R_MIX\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t// Need this to cover the case of the initial read being interpolated\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_MIX\n\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\tif ( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:THREADS_BITS+10-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr[THREADS_BITS+9-ADDRBITSX:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[THREADS_BITS+9-ADDRBITSX:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\tcycle <= cycle_in + 11'd1;\n\t\t\t\t\tif (cycle_in==1023)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t// Will hold at 0 for 9 clocks until set at R_START\n\t\t\t\t\t\tif (fsmstart)\t\t\t// Check data input is ready\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXCtl <= XSload;\t\t// Initial load else we overwrite input NB This is\n\t\t\t\t\t\t\t\t\t\t\t\t// executed on the next cycle, regardless of phase\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\tmstate <= R_START;\t\t// Restart immediately\n\t\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\t\tdatasourceLoad <= 1'b1;\n\t\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// mstate <= R_IDLE;\t\t// Wait for start_flag\n\t\t\t\t\t\t\tmstate <= R_WAIT;\n\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Save result\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_WRITE\n\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\tif ( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:THREADS_BITS+10-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr[THREADS_BITS+9-ADDRBITSX:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[THREADS_BITS+9-ADDRBITSX:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tR_WAIT: begin\n\t\t\t\t\t\tif (fsmstart)\t\t\t// Check data input is ready\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXCtl <= XSload;\t\t// Initial load else we overwrite input NB This is\n\t\t\t\t\t\t\t\t\t\t\t\t// executed on the next cycle, regardless of phase\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\tmstate <= R_START;\t\t// Restart immediately\n\t\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\t\tdatasourceLoad <= 1'b1;\n\t\t\t\t\t\t\tresultsourceRam <= 1'b1;\n\t\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\tend\n\t\t\t\t\n\t\t\t\tR_INT: begin\n\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\tintcycles <= intcycles_in - 1;\n\t\t\t\t\tif (intcycles_in==2)\n\t\t\t\t\t\taddrsourceSave <= 1'b1;\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\tif (intcycles_in==1)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Setup to XOR from saved X0/X1 in ram at next cycle\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\tend\n\t\t\t\t\t// Else mstate remains at R_INT so we continue interpolating\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (mstate==R_MIX)\n\t\t$display (\"phase %d cycle %d Xmix %08x\\n\", phase, cycle-1, Xmix[511:480]);\n`endif\n\tend\t// always @(posedge hash_clk)\nendmodule"
  },
  {
    "path": "ICARUS-LX150/serial.v",
    "content": "// by teknohog, replaces virtual_wire by rs232\n\n// Now using fpgaminer's uart code instead of fpga4fun's. Besides\n// GPL3, the practical difference is that instead of TxD_busy we have\n// its inverse tx_ready.\n\nmodule serial_receive # (\n   parameter baud_rate = 115_200,\n   parameter comm_clk_frequency = 100_000_000 )\n  ( clk, RxD, data1, data2, data3, target, rx_done );\n   input      clk;\n   input      RxD;\n   \n   wire       RxD_data_ready;\n   wire [7:0] RxD_data;\n\n\n   `ifdef CONFIG_SERIAL_TIMEOUT\n\tparameter SERIAL_TIMEOUT = `CONFIG_SERIAL_TIMEOUT;\n   `else\n        // Timeout after 8 million clock at 100Mhz is 80ms, which should be\n        // OK for all sensible clock speeds eg 20MHz is 400ms, 200MHz is 40ms\n\tparameter SERIAL_TIMEOUT = 24'h800000;\n   `endif\n\n   uart_receiver #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(baud_rate)) urx (.clk(clk), .uart_rx(RxD), .tx_new_byte(RxD_data_ready), .tx_byte(RxD_data));\n      \n   output [255:0] data1;\n   output [255:0] data2;\n   output [127:0] data3;\n   output [31:0] target;\n\n   output reg rx_done = 1'b0;\n   \n   // 80 bytes data (including nonce) + 4 bytes target = 84 bytes / 672 bits\n   \n   reg [671:0] input_buffer = 0;\n   reg [671:0] input_copy = 0;\n   reg [6:0]   demux_state = 7'b0000000;\n   reg [23:0]  timer = 0;\n\n   // ltcminer.py sends target first then data\n`ifdef SIM\t// Sane data for simulation - NB disable if simulating serial data loading\n   assign target = input_copy[671:640];\t\t// Not needed since no RxD_data_ready strobe to load targetreg\n   assign data1 = 256'h18e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n   assign data2 = 256'hc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af755756;\n   assign data3 = 128'h0000318f7e71441b141fe951b2b0c7df;\t// NB 0000318f is loaded into nonce\n`else   \n   assign target = input_copy[671:640];\n   assign data3 = input_copy[639:512];\n   assign data2 = input_copy[511:256];\n   assign data1 = input_copy[255:0];\n`endif\n   // kramble: changed this as clock crossing requires timing consistency so\n   // rx_done is now registered and strobes in sync with the data output\n   // hence the following is no longer true...\n   // Needed to reset the nonce for new work. There is a 1-cycle delay\n   // in the main miner loop, because reset only zeroes nonce_next, so\n   // we can do this already at this stage.\n   // assign rx_done = (demux_state == 7'd84);\n   \n   always @(posedge clk)\n     case (demux_state)\n       7'd84:\t\t\t\t// 84 bytes loaded\n\t begin\n\t\trx_done <= 1;\n\t    input_copy <= input_buffer;\n\t    demux_state <= 0;\n\t end\n       \n       default:\n     begin\n        rx_done <= 0;\n\t    if(RxD_data_ready)\n\t      begin\n\t         input_buffer <= input_buffer << 8;\n             input_buffer[7:0] <= RxD_data;\n             demux_state <= demux_state + 1;\n\t         timer <= 0;\n\t      end\n\t      else\n\t      begin\n\t         timer <= timer + 1;\n\t         if (timer == SERIAL_TIMEOUT)\n\t           demux_state <= 0;\n\t      end\n     end // default\n     endcase // case (demux_state)\n   \nendmodule // serial_receive\n\nmodule serial_transmit # (\n   parameter baud_rate = 115_200,\n   parameter comm_clk_frequency = 100_000_000 )\n  (clk, TxD, busy, send, word);\n   \n   // split 4-byte output into bytes\n\n   wire TxD_start;\n   wire TxD_ready;\n   \n   reg [7:0]  out_byte = 0;\n   reg        serial_start = 0;\n   reg [3:0]  mux_state = 4'b0000;\n\n   assign TxD_start = serial_start;\n\n   input      clk;\n   output     TxD;\n   \n   input [31:0] word;\n   input \tsend;\n   output \tbusy;\n\n   reg [31:0] \tword_copy = 0;\n   \n   assign busy = (|mux_state);\n\n   always @(posedge clk)\n     begin\n\t// Testing for busy is problematic if we are keeping the\n\t// module busy all the time :-/ So we need some wait stages\n\t// between the bytes.\n\n\tif (!busy && send)\n\t  begin\n\t     mux_state <= 4'b1000;\n\t     word_copy <= word;\n\t  end  \n\n\telse if (mux_state[3] && ~mux_state[0] && TxD_ready)\n\t  begin\n\t     serial_start <= 1;\n\t     mux_state <= mux_state + 1;\n\n\t     out_byte <= word_copy[31:24];\n\t     word_copy <= (word_copy << 8);\n\t  end\n\t\n\t// wait stages\n\telse if (mux_state[3] && mux_state[0])\n\t  begin\n\t     serial_start <= 0;\n\t     if (TxD_ready) mux_state <= mux_state + 1;\n\t  end\n     end\n\n   uart_transmitter #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(baud_rate)) utx (.clk(clk), .uart_tx(TxD), .rx_new_byte(TxD_start), .rx_byte(out_byte), .tx_ready(TxD_ready));\n\nendmodule // serial_send\n"
  },
  {
    "path": "ICARUS-LX150/serial_hub.v",
    "content": "module slave_receive # (\n\tparameter comm_clk_frequency = 100000000,\n\tparameter baud_rate = 115200\n) (clk, RxD, nonce, new_nonce);\n\n   // Serial receive buffer for a 4-byte nonce\n \n   input      clk;\n   input      RxD;\n\n   wire       RxD_data_ready;\n   wire [7:0] RxD_data;\n\n   uart_receiver #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(baud_rate)) urx (.clk(clk), .uart_rx(RxD), .tx_new_byte(RxD_data_ready), .tx_byte(RxD_data));\n\n   // Tell the main hub code that we have new data\n   output reg\t new_nonce = 0;\n   \n   reg [31:0] input_buffer;\n   output reg [31:0] nonce = 0;\n   reg [2:0]  demux_state = 3'b0;\n   \n   always @(posedge clk)\n     begin\n\tcase (demux_state)\n\t  3'b100:\n\t    begin\n\t       nonce <= input_buffer;\n\t       demux_state <= 0;\n\t       new_nonce <= 1;\n\t    end\n\t  \n\t  default:\n\t    begin\n\t       new_nonce <= 0;\n\t       if(RxD_data_ready)\n\t\t begin\n\t\t    input_buffer <= input_buffer << 8;\n\t\t    input_buffer[7:0] <= RxD_data;\n\t\t    demux_state <= demux_state + 1;\n\t\t end\n\t    end\n\tendcase // case (demux_state)\n     end // always @ (posedge clk)\nendmodule // slave_receive\n   \n// For transmission, we can use the same serial_transmit as the miners\n"
  },
  {
    "path": "ICARUS-LX150/test_icarus.v",
    "content": "// Testbench for ltcminer_icarus.v\n\n`timescale 1ns/1ps\n\n`ifdef SIM\t\t\t\t\t// Avoids wrong top selected if included in ISE/PlanAhead sources\nmodule test_ltcminer ();\n\n\treg clk = 1'b0;\n\treg [31:0] cycle = 32'd0;\n\n\tinitial begin\n\t\tclk = 0;\n\t\t\n\t\twhile(1)\n\t\tbegin\n\t\t\t#5 clk = 1; #5 clk = 0;\n\t\tend\n\tend\n\n\talways @ (posedge clk)\n\tbegin\n\t\tcycle <= cycle + 32'd1;\n\tend\n\t\n\t// Running with default zero's for the data1..3 regs.\n\t// tx_hash=553a4b69b43913a61b42013ce210f713eaa7332e48cda1bdf3b93b10161d0876 at 187,990 nS and\n\t// final_hash (if SIM is defined) at 188,000 nS with golden_nonce_match flag NOT set since it is\n\t// not a diff=32 share. To test golden_nonce, just tweak the target eg 31'hffffffff will match everything\n\t\n\t// With serial input(at comm_clk_frequency=1_000_000), we get rx_done at t=70,220nS, however there is already a\n\t// PBKDF2_SHA256_80_128 loaded in Xbuf (for nonce=00000001). The first final_hash at 188,000 nS is corrupted as\n\t// the input data has changed from all 0's. The Xbuf starts salsa rom at t=188,000 but the nonce is incorrectly\n\t// taken from the newly loaded data so once salsa in complete it also generates a corrupt final_hash at ~362,000 nS.\n\t// Nonce is incremented then the newly loaded data starts PBKDF2_SHA256_80_128, so we must supply a nonce 1 less\n\t// than the expected golden_nonce. The correct PBKDF2_SHA256_80_128 is ready at ~ 197,000 nS. We get final_hash for\n\t// the corrupted work at ~362,000 nS then our required golden_nonce is at 536,180 nS.\n\t// This is only really a problem for simulation. With live hashing we just lose 2 nonces every time getwork is\n\t// loaded, which isn't a big deal.\n\t\t\n\twire RxD;\n\twire TxD;\n\twire extminer_rxd = 0;\n\twire extminer_txd;\n\twire [3:0] dip = 0;\n\twire [3:0] led;\n\twire TMP_SCL=1, TMP_SDA=1, TMP_ALERT=1;\n\t\n\tparameter comm_clk_frequency = 1_000_000;\t// Speeds up serial loading enormously rx_done is at t=70,220nS\n\tparameter baud_rate = 115_200;\n\t\n\tltcminer_icarus #(.comm_clk_frequency(comm_clk_frequency)) uut\n\t\t(clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\t// Send serial data - 84 bytes, matches on nonce 318f (included in data)\n\t// NB starting nonce is 381e NOT 381f (see note above)\n\t\n\t// NORMAL...\n\t// reg [671:0] data = 672'h000007ff0000318e7e71441b141fe951b2b0c7dfc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af75575618e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\n\t// DYNPLL...\n\treg [671:0] data = 672'h55aa07ff0000318e7e71441b141fe951b2b0c7dfc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af75575618e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\t\n\treg\t\t\tserial_send = 0;\n\twire\t\tserial_busy;\n\treg [31:0]\tdata_32 = 0;\n\treg [31:0]\tstart_cycle = 0;\n\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(baud_rate)) sertx (.clk(clk), .TxD(RxD), .send(serial_send), .busy(serial_busy), .word(data_32));\n\n\t// TUNE this according to comm_clk_frequency so we send a single getwork (else it gets overwritten with 0's)\n\t// parameter stop_cycle = 7020;\t\t// For comm_clk_frequency=1_000_000\n\tparameter stop_cycle = 0;\t\t\t// Use this to DISABLE sending data\n\talways @ (posedge clk)\n\tbegin\n\t\tserial_send <= 0;\t\t\t\t// Default\n\t\t// Send data every time tx goes idle (NB the !serial_send is to prevent serial_send\n\t\t// going high for two cycles since serial_busy arrives one cycle after serial_send)\n\t\tif (cycle > 5 && cycle < stop_cycle && !serial_busy && !serial_send)\n\t\tbegin\n\t\t\tserial_send <= 1;\n\t\t\tdata_32 <= data[671:640];\n\t\t\tdata <= { data[639:0], 32'd0 };\n\t\t\tstart_cycle <= cycle;\t\t// Remember each start cycle (makes debugging easier)\n\t\tend\n\tend\n\nendmodule\n`endif"
  },
  {
    "path": "ICARUS-LX150/uart_receiver.v",
    "content": "/*\n*\n* Copyright (c) 2011-2013 fpgaminer@bitcoin-mining.com\n*\n*\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n/*\n* When tx_ready is high, uart_transmitter is ready to send a new byte. Drive\n* rx_new_byte high for one cycle, and the byte to transmit on rx_byte for one\n* cycle.\n*/\nmodule uart_receiver # (\n\tparameter comm_clk_frequency = 100000000,\n\tparameter baud_rate = 115200\n) (\n\tinput clk,\n\n\t// UART interface\n\tinput uart_rx,\n\n\t// Data received\n\toutput reg tx_new_byte = 1'b0,\n\toutput reg [7:0] tx_byte = 8'd0\n);\n\n\tlocalparam [15:0] baud_delay = (comm_clk_frequency / baud_rate) - 1;\n\n\t//-----------------------------------------------------------------------------\n\t// UART Filtering\n\t//-----------------------------------------------------------------------------\n\twire rx;\n\n\tuart_filter uart_fitler_blk (\n\t\t.clk (clk),\n\t\t.uart_rx (uart_rx),\n\t\t.tx_rx (rx)\n\t);\n\n\n\t//-----------------------------------------------------------------------------\n\t// UART Decoding\n\t//-----------------------------------------------------------------------------\n\treg old_rx = 1'b1, idle = 1'b1;\n\treg [15:0] delay_cnt = 16'd0;\n\treg [8:0] incoming = 9'd0;\n\n\talways @ (posedge clk)\n\tbegin\n\t\told_rx <= rx;\n\t\ttx_new_byte <= 1'b0;\n\n\t\tdelay_cnt <= delay_cnt + 16'd1;\n\n\t\tif (delay_cnt == baud_delay)\n\t\t\tdelay_cnt <= 0;\n\n\t\tif (idle && old_rx && !rx)    // Start bit (falling edge)\n\t\tbegin\n\t\t\tidle <= 1'b0;\n\t\t\tincoming <= 9'd511;\n\t\t\tdelay_cnt <= 16'd0;   // Synchronize timer to falling edge\n\t\tend\n\t\telse if (!idle && (delay_cnt == (baud_delay >> 1)))\n\t\tbegin\n\t\t\tincoming <= {rx, incoming[8:1]};    // LSB first\n\n\t\t\tif (incoming == 9'd511 && rx)       // False start bit\n\t\t\t\tidle <= 1'b1;\n\t\t\n\t\t\tif (!incoming[0])    // Expecting stop bit\n\t\t\tbegin\n\t\t\t\tidle <= 1'b1;\n\t\t\t\t\n\t\t\t\tif (rx)\n\t\t\t\tbegin\n\t\t\t\t\ttx_new_byte <= 1'b1;\n\t\t\t\t\ttx_byte <= incoming[8:1];\n\t\t\t\tend\n\t\t\tend\n\t\tend\n\tend\n\nendmodule\n\n\n/*\n* Provides metastability protection, and some minimal noise filtering.\n* Noise is filtered with a 3-way majority vote. This removes any random single\n* 'clk' cycle errors.\n*/\nmodule uart_filter (\n\tinput clk,\n\tinput uart_rx,\n\toutput reg tx_rx = 1'b0\n);\n\n\t//-----------------------------------------------------------------------------\n\t// Metastability Protection\n\t//-----------------------------------------------------------------------------\n\treg rx, meta;\n\n\talways @ (posedge clk)\n\t\t{rx, meta} <= {meta, uart_rx};\n\n\n\t//-----------------------------------------------------------------------------\n\t// Noise Filtering\n\t//-----------------------------------------------------------------------------\n\twire sample0 = rx;\n\treg sample1, sample2;\n\n\talways @ (posedge clk)\n\tbegin\n\t\t{sample2, sample1} <= {sample1, sample0};\n\n\t\tif ((sample2 & sample1) | (sample1 & sample0) | (sample2 & sample0))\n\t\t\ttx_rx <= 1'b1;\n\t\telse\n\t\t\ttx_rx <= 1'b0;\n\tend\n\nendmodule\n"
  },
  {
    "path": "ICARUS-LX150/uart_transmitter.v",
    "content": "/*\n*\n* Copyright (c) 2011-2013 fpgaminer@bitcoin-mining.com\n*\n*\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n/*\n* When tx_ready is high, uart_transmitter is ready to send a new byte. Drive\n* rx_new_byte high for one cycle, and the byte to transmit on rx_byte for one\n* cycle.\n*/\nmodule uart_transmitter # (\n\tparameter comm_clk_frequency = 100000000,\n\tparameter baud_rate = 115200\n) (\n\tinput clk,\n\n\t// UART interface\n\toutput uart_tx,\n\n\t// Data to send\n\tinput rx_new_byte,\n\tinput [7:0] rx_byte,\n\n\t// Status\n\toutput tx_ready\n);\n\n\tlocalparam [15:0] baud_delay = (comm_clk_frequency / baud_rate) - 1;\n\n\treg [15:0] delay_cnt = 16'd0;\n\treg [9:0] state = 10'd1023, outgoing = 10'd1023;\n\n\tassign uart_tx = outgoing[0];\n\tassign tx_ready = state[0] & ~rx_new_byte;\n\n\n\talways @ (posedge clk)\n\tbegin\n\t\tdelay_cnt <= delay_cnt + 16'd1;\n\n\t\tif (delay_cnt >= baud_delay)\n\t\tbegin\n\t\t\tdelay_cnt <= 16'd0;\n\t\t\tstate <= {1'b1, state[9:1]};\n\t\t\toutgoing <= {1'b1, outgoing[9:1]};\n\t\tend\n\n\t\tif (rx_new_byte && state[0])\n\t\tbegin\n\t\t\tdelay_cnt <= 16'd0;\n\t\t\tstate <= 10'd0;\n\t\t\toutgoing <= {1'b1, rx_byte, 1'b0};\n\t\tend\n\tend\n\nendmodule\n"
  },
  {
    "path": "ICARUS-LX150/xilinx_dyn_pll.v",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 1995-2011 Xilinx, Inc.  All rights reserved.\n////////////////////////////////////////////////////////////////////////////////\n//   ____  ____ \n//  /   /\\/   / \n// /___/  \\  /    Vendor: Xilinx \n// \\   \\   \\/     Version : 13.1\n//  \\   \\         Application : xaw2verilog\n//  /   /         Filename : main_pll.v\n// /___/   /\\     Timestamp : 06/03/2011 01:58:13\n// \\   \\  /  \\ \n//  \\___\\/\\___\\ \n//\n//Command: xaw2verilog -st /home/teknohog/dcm2/ipcore_dir/./main_pll.xaw /home/teknohog/dcm2/ipcore_dir/./main_pll\n//Design Name: main_pll\n//Device: xc3s500e-4fg320\n//\n// Module main_pll\n// Generated by Xilinx Architecture Wizard\n// Written for synthesis tool: XST\n\n`timescale 1ns / 1ps\n\nmodule dyn_pll # (parameter SPEED_MHZ = 25 )\n\t(CLKIN_IN, \n\tCLKFX1_OUT, \n\tCLKFX2_OUT, \n\tCLKDV_OUT,\n\tDCM_SP_LOCKED_OUT,\n\tdcm_progclk,\n\tdcm_progdata,\n\tdcm_progen,\n\tdcm_reset,\n\tdcm_progdone,\n\tdcm_locked,\n\tdcm_status);\n\t\n\tinput CLKIN_IN;\n\twire CLKIN_IBUFG_OUT;\n\twire CLK0_OUT;\n\toutput CLKFX1_OUT;\n\toutput CLKFX2_OUT;\n\toutput CLKDV_OUT;\n\toutput DCM_SP_LOCKED_OUT;\n\n\tinput dcm_progclk;\n\tinput dcm_progdata;\n\tinput dcm_progen;\n\tinput dcm_reset;\n\toutput dcm_progdone;\n\toutput dcm_locked;\n\toutput [2:1] dcm_status;\n\t\n\twire CLKFB_IN;\n\twire CLKIN_IBUFG;\n\twire CLK0_BUF;\n\twire CLKFX1_BUF;\n\twire CLKFX2_BUF;\n\twire CLKDV_BUF;\n\twire GND_BIT;\n\twire dcm_progclk_buf;\n\n\tassign GND_BIT = 0;\n\tassign CLKIN_IBUFG_OUT = CLKIN_IBUFG;\n\tassign CLK0_OUT = CLKFB_IN;\n\t\n\tIBUFG  CLKIN_IBUFG_INST (.I(CLKIN_IN), \n\t\t.O(CLKIN_IBUFG));\n\tBUFG  CLK0_BUFG_INST (.I(CLK0_BUF), \n\t\t.O(CLKFB_IN));\n\tBUFG  CLKFX1_BUFG_INST (.I(CLKFX1_BUF), \n\t\t.O(CLKFX1_OUT));\n\tBUFG  CLKFX2_BUFG_INST (.I(CLKFX2_BUF), \n\t\t.O(CLKFX2_OUT));\n\tBUFG  CLKDV_BUFG_INST (.I(CLKDV_BUF), \n\t\t.O(CLKDV_OUT));\n\tBUFG  DCMPROGCLK_BUFG_INST (.I(dcm_progclk), \n\t\t.O(dcm_progclk_buf));\n\n\t// 100 MHZ osc gives fixed 50MHz CLKFX1, 12.5MHZ CLKDV\n\tDCM_SP #( .CLK_FEEDBACK(\"1X\"), .CLKDV_DIVIDE(8.0), .CLKFX_DIVIDE(8),\n\t\t.CLKFX_MULTIPLY(4), .CLKIN_DIVIDE_BY_2(\"FALSE\"), \n\t\t.CLKIN_PERIOD(10.000), .CLKOUT_PHASE_SHIFT(\"NONE\"), \n\t\t.DESKEW_ADJUST(\"SYSTEM_SYNCHRONOUS\"), .DFS_FREQUENCY_MODE(\"LOW\"), \n\t\t.DLL_FREQUENCY_MODE(\"LOW\"), .DUTY_CYCLE_CORRECTION(\"TRUE\"), \n\t\t.FACTORY_JF(16'hC080), .PHASE_SHIFT(0), .STARTUP_WAIT(\"FALSE\") ) \n\t\tDCM_SP_INST (.CLKFB(CLKFB_IN), \n\t\t.CLKIN(CLKIN_IBUFG), \n\t\t.DSSEN(GND_BIT), \n\t\t.PSCLK(GND_BIT), \n\t\t.PSEN(GND_BIT), \n\t\t.PSINCDEC(GND_BIT), \n\t\t.RST(GND_BIT), \n\t\t.CLKDV(CLKDV_BUF), \n\t\t.CLKFX(CLKFX1_BUF), \n\t\t.CLKFX180(), \n\t\t.CLK0(CLK0_BUF), \n\t\t.CLK2X(), \n\t\t.CLK2X180(), \n\t\t.CLK90(), \n\t\t.CLK180(), \n\t\t.CLK270(), \n\t\t.LOCKED(DCM_SP_LOCKED_OUT), \n\t\t.PSDONE(), \n\t\t.STATUS());\n\n\tDCM_CLKGEN #(\n\t\t.CLKFX_DIVIDE(100),\t\t\t// 100Mhz osc so gives steps of 1MHz\n\t\t.CLKFX_MULTIPLY(SPEED_MHZ),\n\t\t.CLKFXDV_DIVIDE(2),\t\t\t// Unused\n\t\t.CLKIN_PERIOD(10.0),\n\t\t.CLKFX_MD_MAX(0.000),\n\t\t.SPREAD_SPECTRUM(\"NONE\"),\n\t\t.STARTUP_WAIT(\"FALSE\")\n\t\t) \n\t\tDCM_CLKGEN_INST (\n\t\t.CLKIN(CLKIN_IBUFG),\n\t\t.CLKFX(CLKFX2_BUF),\n\t\t.FREEZEDCM(1'b0),\n\t\t.PROGCLK(dcm_progclk_buf),\n\t\t.PROGDATA(dcm_progdata),\n\t\t.PROGEN(dcm_progen),\n\t\t.PROGDONE(dcm_progdone),\n\t\t.LOCKED(dcm_locked),\n\t\t.STATUS(dcm_status),\n\t\t.RST(dcm_reset)\n\t\t);\n\nendmodule\n"
  },
  {
    "path": "ICARUS-LX150/xilinx_pll.v",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 1995-2011 Xilinx, Inc.  All rights reserved.\n////////////////////////////////////////////////////////////////////////////////\n//   ____  ____ \n//  /   /\\/   / \n// /___/  \\  /    Vendor: Xilinx \n// \\   \\   \\/     Version : 13.1\n//  \\   \\         Application : xaw2verilog\n//  /   /         Filename : main_pll.v\n// /___/   /\\     Timestamp : 06/03/2011 01:58:13\n// \\   \\  /  \\ \n//  \\___\\/\\___\\ \n//\n//Command: xaw2verilog -st /home/teknohog/dcm2/ipcore_dir/./main_pll.xaw /home/teknohog/dcm2/ipcore_dir/./main_pll\n//Design Name: main_pll\n//Device: xc3s500e-4fg320\n//\n// Module main_pll\n// Generated by Xilinx Architecture Wizard\n// Written for synthesis tool: XST\n\n// kramble manually tweaked for 100MHz CLKIN_IN, programmable CLKFX_OUT and 100Mhz CLK0_OUT\n// NB SPEED_MHZ resolution is 5MHz as CLKFX_DIVIDE(100) seemed excessive so using CLKFX_DIVIDE(20)\n\n`timescale 1ns / 1ps\n\nmodule main_pll # (parameter SPEED_MHZ = 25 )\n\t\t\t(CLKIN_IN, \n             CLKIN_IBUFG_OUT, \n             CLK0_OUT, \n             CLKFX_OUT, \n\t\t\t CLKDV_OUT,\n             LOCKED_OUT);\n\n    input CLKIN_IN;\n   output CLKIN_IBUFG_OUT;\n   output CLK0_OUT;\n   output CLKFX_OUT;\n   output CLKDV_OUT;\n   output LOCKED_OUT;\n   \n   wire CLKFB_IN;\n   wire CLKIN_IBUFG;\n   wire CLK0_BUF;\n   wire CLKFX_BUF;\n   wire CLKDV_BUF;\n   wire GND_BIT;\n   \n   assign GND_BIT = 0;\n   assign CLKIN_IBUFG_OUT = CLKIN_IBUFG;\n   assign CLK0_OUT = CLKFB_IN;\n   IBUFG  CLKIN_IBUFG_INST (.I(CLKIN_IN), \n                           .O(CLKIN_IBUFG));\n   BUFG  CLK0_BUFG_INST (.I(CLK0_BUF), \n                        .O(CLKFB_IN));\n   BUFG  CLKFX_BUFG_INST (.I(CLKFX_BUF), \n                         .O(CLKFX_OUT));\n   BUFG  CLKDV_BUFG_INST (.I(CLKDV_BUF), \n                         .O(CLKDV_OUT));\n   DCM_SP #( .CLK_FEEDBACK(\"1X\"), .CLKDV_DIVIDE(8.0), .CLKFX_DIVIDE(20),\n         .CLKFX_MULTIPLY(SPEED_MHZ/5), .CLKIN_DIVIDE_BY_2(\"FALSE\"), \n         .CLKIN_PERIOD(10.000), .CLKOUT_PHASE_SHIFT(\"NONE\"), \n         .DESKEW_ADJUST(\"SYSTEM_SYNCHRONOUS\"), .DFS_FREQUENCY_MODE(\"LOW\"), \n         .DLL_FREQUENCY_MODE(\"LOW\"), .DUTY_CYCLE_CORRECTION(\"TRUE\"), \n         .FACTORY_JF(16'hC080), .PHASE_SHIFT(0), .STARTUP_WAIT(\"FALSE\") ) \n         DCM_SP_INST (.CLKFB(CLKFB_IN), \n                       .CLKIN(CLKIN_IBUFG), \n                       .DSSEN(GND_BIT), \n                       .PSCLK(GND_BIT), \n                       .PSEN(GND_BIT), \n                       .PSINCDEC(GND_BIT), \n                       .RST(GND_BIT), \n                       .CLKDV(CLKDV_BUF), \n                       .CLKFX(CLKFX_BUF), \n                       .CLKFX180(), \n                       .CLK0(CLK0_BUF), \n                       .CLK2X(), \n                       .CLK2X180(), \n                       .CLK90(), \n                       .CLK180(), \n                       .CLK270(), \n                       .LOCKED(LOCKED_OUT), \n                       .PSDONE(), \n                       .STATUS());\nendmodule\n"
  },
  {
    "path": "ICARUS-LX150/xilinx_ram.v",
    "content": "// xilinx_ram.v - inferring the ram seems to work fine\n\nmodule ram # ( parameter ADDRBITS=10 ) (\n\traddr,\n\twaddr,\n\tclock,\n\tdata,\n\twren,\n\tq);\n\n\tinput\t[ADDRBITS-1:0]  raddr;\n\tinput\t[ADDRBITS-1:0]  waddr;\n\tinput\t  clock;\n\tinput\t[255:0]  data;\n\tinput\t  wren;\n\toutput\t[255:0]  q;\n\n\t//synthesis attribute ram_style of store is block\n\treg [255:0] store [(2 << (ADDRBITS-1))-1:0];\n\treg[ADDRBITS-1:0] raddr_reg;\n\t\n\talways @ (posedge clock)\n\tbegin\n\t\traddr_reg <= raddr;\n\t\tif (wren)\n\t\t\tstore[waddr] <= data;\n\tend\n\t\n\tassign q = store[raddr_reg];\n\t\t\t\nendmodule"
  },
  {
    "path": "LICENSE.txt",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "README.txt",
    "content": "An Open Source FPGA Litecoin (scrypt) miner\n\nThis code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\nwithout even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\nSee the GNU General Public License for more details.\n\nProject includes code from https://github.com/progranism/Open-Source-FPGA-Bitcoin-Miner\nScrypt algorithm is based on https://github.com/ckolivas/cgminer/blob/master/scrypt.c\nDiscussion is at https://forum.litecoin.net/index.php/topic,5162.0.html\n\nSpecial thanks to fpgaminer for the original bitcoin mining code, teknohog for his\nLX150 code, also OrphanedGland, udif, TheSeven, makomk, and newMeat1 as credited on\nthe fpgaminer bitcoin thread https://bitcointalk.org/index.php?topic=9047.0 and ngzhang\nfor his Icarus/Lancelot boards and github.\n\nThe scrypt algorithm is implemented using on-chip FPGA RAM, so should be portable to any\nFPGA large enough to support 1024kBit of RAM (512kBit with interpolation, eg DE0-Nano).\nExternal RAM support could be added, but requires the relevant RAM controller for the\nboard. Performance will be limited by RAM bandwidth.\n\nThe code is proof of concept, further optimisation is required (only a small performance\ngain is to be expected though). Internal (pll derived) clock is only 25MHz, limited by\nthe salsa_core. Further pipelining would increase this, but gives no performance gain\nsince the scrypt algorithm is essentially serial. RAM is also clocked at this speed, a\nfaster clock would help improve performance a little (and is essential for external RAM)\nat the expense of complexity.\n\nMultiple cores are best implemented using the 512kBit scratchpad as the slower individual\nthroughput is more than compensated by doubling the number of cores supported. MULTICORE\nis now the default. This only affects nonce handling so its safe to use with singe cores\nwhich will simply scan a more limited range (the top nibble is fixed at 0). To revert to\nthe previous behaviour set the NOMULTICORE macro (but ONLY if using a single core).\n\nContents\n--------\nDE2-115-Single  Single full scratchpad core, this is the simplest implementation.\n\nDE0-Nano        Uses interpolation as the full scratchpad does not fit (this is the\n                same as LOOKUP_GAP=2 in GPU). Test results ...\n                1.16 kHash/sec at 25Mhz (this is Fmax at 85C/Slow model)\n                2.09 kHash/sec at 45Mhz\n                Fmax is 25MHz, so anything greater may not work reliably on your device.\n                BEWARE the onboard psu regulators run HOT to VERY HOT. You may fry them!\n\nexperimental    New code, not all fully working.\n\nICARUS-LX150    A Xilinx LX150 multicore port for ngzhang's Icarus/Lancelot boards.\n\nscripts         Mining scripts.\n\nsource          Verilog source code.\n\nZtex and Cairnsmore CM1\n-----------------------\nPorts for the Ztex 1.15y and Cairnsmore CM1 quad boards are available in the experimental\nfolder. Both achieve around 60kHash/sec (total for all four FPGA devices) using a single\ncore and 16 threads (identical to the current ICARUS-LX150 code). A customised version of\ncgminer 3.1.1 must be used (see experimental/Ztex-1-15y/cgminer-3.1.1 which supports both\nboards). Bitstreams are linked in the respective READMEs.\n\nUsage\n-----\nThe Altera ports (DE0-Nano) require installation of Quartus II software. For MS Windows\nset mining pool connection details by editing scripts/config.tcl then run scripts/mine.bat\nThis uses getwork protocol and timeouts may occur. There are some configuration switches\nin mine.tcl, eg it can run in test mode which sends historical block headers to the fpga\nwith known nonce results. Use of a stratum proxy server is recommended."
  },
  {
    "path": "bitstreams.txt",
    "content": "Bitstreams have been uploaded to dropbox ...\n\nexperimental/LX150-SPLIT 05-Sep-2013 12-14khash/sec\n---------------------------------------------------\n\nhttps://www.dropbox.com/s/ox5tvpc0g4htqpj/LX150-SPLIT-rel-10-4fullcore-25MHz.7z\n\nhttps://www.dropbox.com/s/cqioj30zahszh43/LX150-SPLIT-rel-10-4fullcore-30MHz.7z\n\nICARUS-LX150 26-Sep-2013 33kHash/sec at 50MHz\n---------------------------------------------\nhttps://www.dropbox.com/s/sietguvi35c7gl1/rel-13-icarus-lx150-25Mhz-max-51Mhz.bit\n\nYou'll need 7zip to uncompress them and IMPACT from the xilinx ISE to program. Download\nand install the full version (not Webpack). No licence is needed to run IMPACT, at\nleast for ISE 14.4 on XP-SP3 (which is my ancient parallel-port PC I use for IMPACT).\nAlso a xilinx JTAG platform cable. The official one is very expensive, cheap clones\nare available on ebay, or if you can do electronics a parallel-port adapter can be\nbuilt for just a few dollars.\n\n"
  },
  {
    "path": "experimental/CM1/README.txt",
    "content": "Litecoin miner Cairnsmore CM1 port\n\nWARNING This is experimental code which may DAMAGE YOUR CAIRNSMORE BOARD.\nUse at your own risk.\n\nThis code is derived from the HashVoodoo FPGA Bitcoin Miner Project\nhttps://github.com/pmumby/hashvoodoo-fpga-bitcoin-miner\n\nLicensed under GPL. My thanks to Paul Mumby (Glasswalker), makomk and TheSeven.\n\nNB This port requires the Hashvoodo controller firmware available at\nhttps://github.com/pmumby/hashvoodoo-fpga-bitcoin-miner/downloads\nUse hashvoodoo_controller_25.bit from any of the later releases, NOT the 08_04_2012.\n\nA single core experimental bitstream is available at ...\nhttps://www.dropbox.com/s/08ccjjvmfgmxcbi/hashvoodoo-ltc-v03ab-1core-fmax-49.bit\n\nThis runs at up to 250MHz (use --cainsmore-clock to override the default 175MHz) giving approx\n60kHash/sec total at the pool (ignore the cgminer stats as they are currently complete garbage).\nNB Note the typo --cainsmore-clock rather than --cairnsmore-clock. This is not yet fixed in the\ncgminer code, so take care with the spelling, sorry).\n\nA dual core bitstream is not yet available (I'm still trying to get the xilinx ISE it to route it,\nthough the single core version above is probably just as effective).\n\nYou will need the patched version of cgminer-3.1.1 from\nhttps://github.com/kramble/FPGA-Litecoin-Miner/tree/master/experimental/Ztex-1-15y/cgminer-3.1.1\n\nNB The cgminer folder location is a bit unfortunate being under ztex, I'll look to moving it when\nthe code is promoted from experimental.\n\n"
  },
  {
    "path": "experimental/CM1/dcm_controller.v",
    "content": "`timescale 1ns / 1ps\n//////////////////////////////////////////////////////////////////////////////////\n// Dynamic DCM Controller. Derived from sources from TheSeven at:\n// https://github.com/progranism/Open-Source-FPGA-Bitcoin-Miner\n// Paul Mumby 2012\n//////////////////////////////////////////////////////////////////////////////////\nmodule dcm_controller (\n\t\tclk,\n\t\tdata2,\n\t\tmidstate,\n\t\tstart,\n\t\tdcm_prog_data,\n\t\tdcm_prog_clk,\n\t\tdcm_prog_done,\n\t\tdcm_prog_en,\n\t\tidentify\n\t);\n\n\t//Parameters:\n\t//================================================\n\tparameter MAXIMUM_MULTIPLIER = 88;\n\tparameter MINIMUM_MULTIPLIER = 20;\n\tparameter INITIAL_MULTIPLIER = 60;\n\tparameter INITIAL_DIVIDER = 10;\n\n\t//IO Definitions:\n\t//================================================\n\tinput clk;\n   input [255:0] midstate;\n\tinput [255:0] data2;\n\tinput start;\n\tinput dcm_prog_clk;\n\toutput dcm_prog_data;\n\toutput dcm_prog_en;\n\tinput dcm_prog_done;\n\toutput identify;\n\t\n\t//Register/Wire Definitions:\n\t//================================================\n\treg dcm_prog_data = 0;\n\treg dcm_prog_en = 0;\n\twire [31:0] cmd_trigger_timestamp;\n\twire cmd_trigger;\n\twire [7:0] cmd_prefix;\n\twire [7:0] cmd_id;\n\twire [7:0] cmd_data;\n\twire [7:0] cmd_validator;\n\twire cmd_valid;\n\treg busy = 0;\n\treg [7:0] cmd_latch_id = 8'd0;\n\treg [7:0] cmd_latch_data = 8'd0;\n\treg dcm_prog_ready = 0;\n\treg [7:0] dcm_multiplier = INITIAL_MULTIPLIER;\n\treg [7:0] current_dcm_multiplier = 8'd0;\n\treg [4:0] dcm_progstate = 5'd31;\n\treg [15:0] dcm_data = 16'd0;\n\twire [7:0] dcm_divider_s1;\n\twire [7:0] dcm_multiplier_s1;\n\treg dcm_prog_ready_b = 0;\n\twire dcm_prog_busy;\n\treg [7:0] dcm_multiplier_b = 8'd0;\n\treg identify = 0;\n\treg [2:0] nonce_dip_bits = 3'd0;\n\twire [12:0] fsm_state;\n\t\n\t//Assignments:\n\t//================================================\n\tassign cmd_trigger_timestamp = data2[63:32];\n\tassign cmd_prefix = data2[231:224];\t\t//data2 byte 29 should always be 10110111 results in xor against 01011010 with id/data\n\tassign cmd_id = data2[239:232];\t\t\t//data2 byte 30\n\tassign cmd_data = data2[247:240];\t\t//data2 byte 31\n\tassign cmd_validator = data2[255:248];\t//data2 byte 32\n\tassign cmd_trigger = (cmd_trigger_timestamp == 32'hffffffff) && (midstate == 256'd0);\n\tassign cmd_valid = cmd_validator == (cmd_prefix ^ cmd_id ^ cmd_data ^ 8'b01101101);\n\tassign dcm_prog_busy = (dcm_progstate != 5'd31);\n\tassign dcm_divider_s1 = INITIAL_DIVIDER-1;\n\tassign dcm_multiplier_s1 = dcm_multiplier_b - 8'd1;\n\tassign fsm_state = {start,cmd_trigger,cmd_valid,busy,dcm_prog_busy,cmd_latch_id};\n\t\n\t//Toplevel Logic:\n\t//================================================\n\t\t\n\t//Main command processor/validation state machine\n\talways @(posedge clk)\n\t\tbegin\n\t\t\tcasex (fsm_state)\n\t\t\t\t13'b1110xxxxxxxxx: begin //(start && cmd_trigger && cmd_valid && ~busy)\n\t\t\t\t\t\t//We're not busy, and We've received the start (data in from uart) \n\t\t\t\t\t\t//and trigger (appropriate malformed packet)\n\t\t\t\t\t\t//And the command passes it's simple validation check\n\t\t\t\t\t\t//So lets decode it, latch the data, and flag busy to handle the command\n\t\t\t\t\t\tcmd_latch_id <= cmd_id;\n\t\t\t\t\t\tcmd_latch_data <= cmd_data;\n\t\t\t\t\t\tbusy <= 1; //Flag we're busy\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\tend\n\t\t\t\t13'bxxx1000000000: begin //(busy && cmd_latch_id==8'd0 && ~dcm_prog_busy)\n\t\t\t\t\t\t//COMMAND: Set Clock\n\t\t\t\t\t\tif(cmd_latch_data > MAXIMUM_MULTIPLIER)\n\t\t\t\t\t\t\tdcm_multiplier <= MAXIMUM_MULTIPLIER;\n\t\t\t\t\t\telse if(cmd_latch_data < MINIMUM_MULTIPLIER)\n\t\t\t\t\t\t\tdcm_multiplier <= MINIMUM_MULTIPLIER;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tdcm_multiplier <= cmd_latch_data;\n\t\t\t\t\t\tdcm_prog_ready <= 1;\n\t\t\t\t\t\tbusy <= 0;\n\t\t\t\t\tend\n\t\t\t\t13'bxxx1x00000001: begin //(busy && cmd_latch_id==8'd1)\n\t\t\t\t\t\t//COMMAND: Identify\n\t\t\t\t\t\tidentify <= cmd_latch_data[0]; //Set identify flag to first bit of command data byte.\n\t\t\t\t\tend\n\t\t\t\t13'bxxx1x00000010: begin //(busy && cmd_latch_id==8'd2)\n\t\t\t\t\t\t//COMMAND: Set Nonce_DIP_Bits\n\t\t\t\t\t\tnonce_dip_bits <= cmd_latch_data[2:0]; //Set number of nonce msb bits to take from chip-specific DIP switches\n\t\t\t\t\tend\t\t\t\n\t\t\t\tdefault: begin\t//else\n\t\t\t\t\t\tdcm_prog_ready <= 0; //stop asserting prog_ready, the programmer has grabbed it by now.\n\t\t\t\t\tend\n\t\t\tendcase\n\t\tend\n\t\t\n\t//DCM Programming logic\n\t//Mostly copied from https://github.com/progranism/Open-Source-FPGA-Bitcoin-Miner\n\t//Adapted to our specific setup\n\talways @(posedge dcm_prog_clk)\n\t\tbegin\n\t\t\t//Clock crossing buffers:\n\t\t\tdcm_prog_ready_b <= dcm_prog_ready;\n\t\t\tdcm_multiplier_b <= dcm_multiplier;\n\t\t\t\n\t\t\tif (dcm_multiplier_b != current_dcm_multiplier && dcm_progstate == 5'd31 && dcm_prog_ready_b)\n\t\t\tbegin\n\t\t\t\tcurrent_dcm_multiplier <= dcm_multiplier_b;\n\t\t\t\tdcm_progstate <= 5'd0;\n\t\t\t\t// DCM expects D-1 and M-1\n\t\t\t\tdcm_data <= {dcm_multiplier_s1, dcm_divider_s1};\n\t\t\tend\n\n\t\t\tif (dcm_progstate == 5'd0) {dcm_prog_en, dcm_prog_data} <= 2'b11;\n\t\t\tif (dcm_progstate == 5'd1) {dcm_prog_en, dcm_prog_data} <= 2'b10;\n\t\t\tif ((dcm_progstate >= 5'd2 && dcm_progstate <= 5'd9) || (dcm_progstate >= 5'd15 && dcm_progstate <= 5'd22))\n\t\t\tbegin\n\t\t\t\tdcm_prog_data <= dcm_data[0];\n\t\t\t\tdcm_data <= {1'b0, dcm_data[15:1]};\n\t\t\tend\n\n\t\t\tif (dcm_progstate == 5'd10) {dcm_prog_en, dcm_prog_data} <= 2'b00;\n\t\t\tif (dcm_progstate == 5'd11) {dcm_prog_en, dcm_prog_data} <= 2'b00;\n\t\t\tif (dcm_progstate == 5'd12) {dcm_prog_en, dcm_prog_data} <= 2'b00;\n\n\t\t\tif (dcm_progstate == 5'd13) {dcm_prog_en, dcm_prog_data} <= 2'b11;\n\t\t\tif (dcm_progstate == 5'd14) {dcm_prog_en, dcm_prog_data} <= 2'b11;\n\n\t\t\tif (dcm_progstate == 5'd23) {dcm_prog_en, dcm_prog_data} <= 2'b00;\n\t\t\tif (dcm_progstate == 5'd24) {dcm_prog_en, dcm_prog_data} <= 2'b00;\n\t\t\tif (dcm_progstate == 5'd25) {dcm_prog_en, dcm_prog_data} <= 2'b10;\n\t\t\tif (dcm_progstate == 5'd26) {dcm_prog_en, dcm_prog_data} <= 2'b00;\n\n\t\t\tif (dcm_progstate <= 5'd25) dcm_progstate <= dcm_progstate + 5'd1;\n\n\t\t\tif (dcm_progstate == 5'd26 && dcm_prog_done)\n\t\t\t\tdcm_progstate <= 5'd31;\n\t\tend\nendmodule\n"
  },
  {
    "path": "experimental/CM1/flasher.v",
    "content": "`timescale 1ns / 1ps\n//////////////////////////////////////////////////////////////////////////////////\n// Simple Clock Divider Style Flasher\n// Paul Mumby 2012\n//////////////////////////////////////////////////////////////////////////////////\nmodule flasher(\n\t\tclk,\n\t\tflash\n\t);\n\n\t//Parameters:\n\t//================================================\n\t\n\t//Number of bits to divide MSB will be the flash output\n\tparameter BITS = 24;\n\t\t\t\t\t\t\t\t\n\t//IO Definitions:\n\t//================================================\n\tinput clk;\n\toutput flash;\n\n\t//Register/Wire Definitions:\n\t//================================================\n\treg [BITS-1:0] counter;\n\t\n\t//Assignments:\n\t//================================================\n\tassign flash = counter[BITS-1];\n\t\n\t//Toplevel Logic:\n\t//================================================\n\talways @(posedge clk)\n\t\tcounter <= counter + 1;\n\nendmodule\n"
  },
  {
    "path": "experimental/CM1/hashvoodoo.ucf",
    "content": "# UCF for a Cairnsmore1 board\nNET \"clk_n\" LOC = \"J1\" |IOSTANDARD = \"LVDS_33\";\t\t\t//25Mhz Differential Source Clock from Controller\nNET \"clk_p\" LOC = \"J3\" |IOSTANDARD = \"LVDS_33\";\t\t\t//25Mhz Differential Source Clock from Controller\nNET \"clk_comm\" LOC = \"C1\" |IOSTANDARD = \"LVCMOS33\";\t//25Mhz Clock for UART from controller\nNET \"clk_comm\" CLOCK_DEDICATED_ROUTE = FALSE;\t\t\t//Grrr...\n\n# serial port receive & transmit\nNET \"RxD\" LOC = \"C3\"\t|IOSTANDARD = \"LVCMOS33\" |PULLUP;\t\t// USB5 input\nNET \"TxD\" LOC = \"F2\" |IOSTANDARD = \"LVCMOS33\" |SLEW=\"QUIETIO\";\t// USB7 output\n\n# LED Array\nNET \"led[0]\" LOC = \"A18\" |IOSTANDARD = \"LVCMOS33\" |SLEW=\"QUIETIO\";\nNET \"led[1]\" LOC = \"B18\" |IOSTANDARD = \"LVCMOS33\" |SLEW=\"QUIETIO\";\nNET \"led[2]\" LOC = \"A17\" |IOSTANDARD = \"LVCMOS33\" |SLEW=\"QUIETIO\";\nNET \"led[3]\" LOC = \"A16\" |IOSTANDARD = \"LVCMOS33\" |SLEW=\"QUIETIO\";\n\n# DIP Switch Array\nNET \"dip[0]\" LOC = \"A4\" |IOSTANDARD = \"LVCMOS33\";\nNET \"dip[1]\" LOC = \"D6\" |IOSTANDARD = \"LVCMOS33\";\nNET \"dip[2]\" LOC = \"C6\" |IOSTANDARD = \"LVCMOS33\";\nNET \"dip[3]\" LOC = \"C8\" |IOSTANDARD = \"LVCMOS33\";\n\n# New split reset architecture:\nNET \"reset_a\" LOC = \"B22\" |IOSTANDARD = \"LVCMOS33\";\nNET \"reset_b\" LOC = \"D1\" |IOSTANDARD = \"LVCMOS33\";\nNET \"reset_select\" LOC = \"D7\" |PULLUP |IOSTANDARD = \"LVCMOS33\";\n\n# Input Clocks from Controller\nNET \"clk_dcm\" TNM_NET = clk_dcm;\nNET \"clk_comm\" TNM_NET = clk_comm;\nTIMESPEC TS_clk_dcm = PERIOD \"clk_dcm\" 49 MHz HIGH 50 %;\nTIMESPEC TS_clk_comm = PERIOD \"clk_comm\" 25 MHz HIGH 50 %;\n\n# Various Timing Ignores\nNET \"clk_dcm\" TNM_NET =  FFS \"GRP_HASH\";\nNET \"clk_comm\" TNM_NET =  FFS \"GRP_COMM\";\nTIMESPEC TS_Boundry1 = FROM \"GRP_HASH\" TO \"GRP_COMM\" TIG ;\nTIMESPEC TS_Boundry2 = FROM \"GRP_COMM\" TO \"GRP_HASH\" TIG ;\n\n#VCCAUX Line Config From makomk\nCONFIG VCCAUX=3.3;\n"
  },
  {
    "path": "experimental/CM1/hashvoodoo.v",
    "content": "`timescale 1ns / 1ps\n//////////////////////////////////////////////////////////////////////////////////\n// HashVoodoo Top Module\n// Paul Mumby 2012\n//////////////////////////////////////////////////////////////////////////////////\nmodule HASHVOODOO (\n\t\tclk_p, \n\t\tclk_n, \n\t\tclk_comm, \n\t\tRxD, \n\t\tTxD, \n\t\tled, \n\t\tdip, \n\t\treset_a, \n\t\treset_b, \n\t\treset_select\n\t);\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n\t//Parameters:\n\t//================================================\n\tparameter CLOCK_RATE = 25000000;\t\t\t\t\t//Input Clock Output from Controller in Hz\n\tparameter DCM_DIVIDER = 10;\t\t\t\t\t\t//Starting point for DCM divider (25Mhz / 10 = 2.5Mhz increments)\n\tparameter DCM_MULTIPLIER_START = 70;\t\t\t//Starting point for DCM multiplier (2.5Mhz x 70 = 175Mhz)\n\tparameter DCM_MULTIPLIER_CAP = 120;\t\t\t\t//Max Point Allowed for DCM multiplier (Safety ceiling) - KRAMBLE now 300MHz\n\tparameter DCM_MULTIPLIER_MIN = 20;\t\t\t\t//Minimum Allowed for DCM multiplier (If it falls below this something is seriously wrong)\n\tparameter UART_BAUD_RATE = 115200;\t\t\t\t//Baud Rate to use for UART (BPS)\n\tparameter UART_SAMPLE_POINT = 8;\t\t\t\t\t//Point in the oversampled wave to sample the bit state for the UART (6-12 should be valid)\n\tparameter CLOCK_FLASH_BITS = 26;\t\t\t\t\t//Number of bits for divider of flasher. (28bit = approx 67M Divider)\n\n// `define DUALCORE\t\t\t\t\t// Comment out for single core (dual core does not currently route)\n\n`ifdef DUALCORE\n\tlocalparam LOCAL_MINERS = 2;\t// One or two cores (configures ADDRBITS automatically)\n`else\n\tlocalparam LOCAL_MINERS = 1;\t// One or two cores (configures ADDRBITS automatically)\n`endif\n\n\tlocalparam ADDRBITS = 12 - clog2(LOCAL_MINERS);\t// Automatically selects largest RAM that will fit LX150\n\tlocalparam SBITS = 8;\t\t// Shift data path width\n\t\n\t//IO Definitions:\n\t//================================================\n   input clk_p;\t\t\t//Input Clock From Controller (P signal of diff pair)\n   input clk_n;\t\t\t//Input Clock From Controller (N signal of diff pair)\n   input clk_comm;\t\t//Input Comm Clock From Controller (Single ended)\n   input RxD;\t\t\t\t//UART RX Pin (From Controller)\n   output TxD;\t\t\t\t//UART TX Pin  (To Controller)\n   output [3:0] led;\t\t//LED Array\n\tinput [3:0]dip;\t\t//DIP Switch Array\n\tinput reset_a;\t\t\t//Reset Signal A (position dependant) from Controller\n\tinput reset_b;\t\t\t//Reset Signal B (position dependant) from Controller\n\tinput reset_select;\t//Reset Selector (hard wired based on position)\n\n\t//Register/Wire Definitions:\n\t//================================================\n\treg reset;\t\t\t\t\t\t\t\t//Actual Reset Signal\n\twire clk_buf;\t\t\t\t\t\t\t//Actually Used Clock Signals\n\twire clk_dcm;\t\t\t\t\t\t\t//Output of hash clock DCM\n\twire clk_comm_buf;\n\twire clock_flash;\t\t\t\t\t\t//Flasher output (24bit divider of clock)\n\twire miner_busy;\t\t\t\t\t\t//Miner Busy Flag\n\twire serial_send;\t\t\t\t\t\t//Serial Send flag, Triggers UART to begin sending what's in it's buffer\n\twire serial_busy;\t\t\t\t\t\t//Serial Busy flag, Indicates the UART is currently working\n\twire [31:0] golden_nonce;\t\t\t\t//Overall Found Golden Nonce\n\twire [255:0] data1, data2;\n\twire [127:0] data3;\n\twire start_mining;\t\t\t\t\t\t//Start Mining flag. This flag going high will trigger the worker to begin hashing on it's buffer\n\twire syncstart_mining;\t\t\t\t\t//Clock crossing (redirected from reset_a in simulation)\n\treg syncstart_mining_d = 1'b0;\n\twire led_nonce_fade;\t\t\t\t\t//This is the output from the fader, jumps to full power when nonce found and fades out\n\twire led_serial_fade;\t\t\t\t\t//Output from fader for serial activity.\n\twire dcm_prog_en;\n\twire dcm_prog_data;\n\twire dcm_prog_done;\n\twire dcm_valid;\n\twire dcm_reset = 1'b0;\n\twire identify_flag;\n\twire identify_flasher;\n\t\n\treg [3:0] syncticket1 = 0;\t\t\t\t//Clock domain sync\n\twire got_ticket1;\t\t\t\t\t\t//Got Ticket flag indicates the local worker found a new nonce.\n`ifdef DUALCORE\n\twire [63:0] slave_nonces;\t\t\t\t//Nonce found by worker\n\treg [1:0] new_nonces;\t\t\t\t\t//Flag indicating new nonces found\n\treg [3:0] syncticket2 = 0;\n\twire got_ticket2;\n`else\n\twire [31:0] slave_nonces;\n\treg [0:0] new_nonces;\t\t\t\t\t//Flag indicating new nonces found\n`endif\n\n\t//Assignments:\n\t//================================================\n\t// KRAMBLE swapped blue and geen leds as blue is far brighter and better as nonce indicator\n\tassign led[0] = (led_serial_fade || identify_flasher);\t\t\t\t//LED0 (Green): UART Activity (blinks and fades on either rx or tx)\n\tassign led[1] = (clock_flash || ~dcm_valid || identify_flasher);\t//LED1 (Red): Clock Heartbeat (blinks to indicate working input clock)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//\t\tOff = no clock\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//\t\tOn Solid = dcm invalid.\n\tassign led[2] = (led_nonce_fade || identify_flasher);\t\t\t\t//LED2 (Blue): New Nonce Beacon (fader)\n\tassign led[3] = (~miner_busy || identify_flasher);\t\t\t\t\t//LED3 (Amber): Idle Indicator. Lights when miner has nothing to do.\n\tassign identify_flasher = (clock_flash && identify_flag);\t\t\t//Identify Mode (ALL LEDs flash with heartbeat)\n\t\n\t//Module Instantiation:\n\t//================================================\n\n`ifndef SIM\t\n\t//LVDS Clock Buffer\n\tIBUFGDS #(\n\t\t\t.DIFF_TERM(\"TRUE\"),\n\t\t\t.IOSTANDARD(\"DEFAULT\")\n\t\t) CLK_LVDS_BUF (\n\t\t\t.O(clk_buf),\n\t\t\t.I(clk_p),\t//Diff_p clock input\n\t\t\t.IB(clk_n)\t//Diff_n clock input\n\t\t);\n\t\n\t//Comm Clock Buffer\n\tBUFG CLK_COMM_BUF\n\t\t(\n\t\t\t.I   (clk_comm),\n\t\t\t.O   (clk_comm_buf)\n\t\t);\n\n\t//Dynamically Programmable Hash Clock DCM\n\tmain_dcm #(\n\t\t\t.DCM_DIVIDER(DCM_DIVIDER),\n\t\t\t.DCM_MULTIPLIER(DCM_MULTIPLIER_START)\n\t\t) MAINDCM(\n\t\t\t.RESET(dcm_reset),\n\t\t\t.CLK_VALID(dcm_valid),\n\t\t\t.CLK_OSC(clk_buf), \n\t\t\t.CLK_HASH(clk_dcm),\t\t\t// KRAMBLE now divide 4 (typically 50MHz for nominal 200MHz)\n\t\t\t.PROGCLK(clk_comm_buf),\n\t\t\t.PROGDATA(dcm_prog_data),\n\t\t\t.PROGEN(dcm_prog_en),\n\t\t\t.PROGDONE(dcm_prog_done)\n\t\t);\n`else\n\tassign clk_buf = clk_p;\n\tassign clk_dcm = clk_buf;\n\tassign clk_comm_buf = clk_comm;\n`endif\n\n\t//DCM Controller Core (controls dcm clock based on special (malformed) icarus work packets which act as \"command\" packets\n\tdcm_controller #(\n\t\t\t.MAXIMUM_MULTIPLIER(DCM_MULTIPLIER_CAP),\n\t\t\t.MINIMUM_MULTIPLIER(DCM_MULTIPLIER_MIN),\n\t\t\t.INITIAL_MULTIPLIER(DCM_MULTIPLIER_START),\n\t\t\t.INITIAL_DIVIDER(DCM_DIVIDER)\n\t\t) DCM_CONTROL (\n\t\t\t.clk(clk_comm_buf),\n\t\t\t.data2({data2[255:96], data3[95:0]}),\t// KRAMBLE Align with timestamp field in data3\n\t\t\t.midstate(data1),\t\t\t\t\t\t// KRAMBLE all zero's for valid command packet\n\t\t\t.start(start_mining),\n\t\t\t.dcm_prog_clk(clk_comm_buf),\n\t\t\t.dcm_prog_en(dcm_prog_en),\n\t\t\t.dcm_prog_data(dcm_prog_data),\n\t\t\t.dcm_prog_done(dcm_prog_done),\n\t\t\t.identify(identify_flag)\n\t\t);\n\t\n\t//Hub core, this is a holdover from Icarus. KRAMBLE: now in use since multiple hasher cores.\n   hub_core #(\n\t\t\t.SLAVES(LOCAL_MINERS)\n\t\t) HUBCORE (\n\t\t\t.hash_clk(clk_comm_buf), \n\t\t\t.new_nonces(new_nonces), \n\t\t\t.golden_nonce(golden_nonce), \n\t\t\t.serial_send(serial_send), \n\t\t\t.serial_busy(serial_busy), \n\t\t\t.slave_nonces(slave_nonces)\n\t\t);\n\t\n\t//New Serial Core. Handles all communications in and out to the host.\n\twire unused_rx_busy;\n\t\n\tserial_core #(\n\t\t\t.CLOCK(CLOCK_RATE),\n\t\t\t.BAUD(UART_BAUD_RATE),\n\t\t\t.SAMPLE_POINT(UART_SAMPLE_POINT)\n\t\t) SERIAL_COMM (\n\t\t\t.clk(clk_comm_buf),\n\t\t\t.rx(RxD),\n\t\t\t.tx(TxD),\n\t\t\t.rx_ready(start_mining),\n\t\t\t.tx_ready(serial_send),\n\t\t\t.data1(data1),\n\t\t\t.data2(data2),\n\t\t\t.data3(data3),\n\t\t\t.word(golden_nonce),\n\t\t\t.tx_busy(serial_busy),\n\t\t\t.rx_busy(unused_rx_busy)\n\t\t);\n\t\n\twire [31:0] unused_nonce_out1, unused_hash_out1;\n\twire [31:0] unused_nonce_out2, unused_hash_out2;\n\t\n\t// NB For now using same clk for both P and S\n\n\treg loadnonce = 1'b0;\t// Generate loadnonce strobe for new work (NB this initiates a full engine reset)\n\treg [3:0]syncloadnonce = 3'd0;\n\n\twire [31:0] mod_target = 32'h00007fff;\t\t\t// Hard coded for diff=2\n\n\twire gn_match_1;\n\twire [31:0] golden_nonce_1;\n\twire [31:0] hash_1, nonce_out_1;\t\t\t\t// nonce_out_1 used for miner_busy\n\twire salsa_busy_1, salsa_result_1, salsa_reset_1, salsa_start_1, salsa_shift_1;\n\twire [SBITS-1:0] salsa_din_1;\n\twire [SBITS-1:0] salsa_dout_1;\n\n\tpbkdfengine #(.SBITS(SBITS)) P1\n\t\t(.hash_clk(clk_dcm), .pbkdf_clk(clk_dcm), .data1(data1), .data2(data2), .data3(data3), .target(mod_target),\n\t\t.nonce_msb( 4'd0 ), .nonce_out(nonce_out_1), .golden_nonce_out(golden_nonce_1),\n\t\t.golden_nonce_match(gn_match_1), .loadnonce(loadnonce),\n\t\t.salsa_din(salsa_din_1), .salsa_dout(salsa_dout_1), .salsa_busy(salsa_busy_1), .salsa_result(salsa_result_1),\n\t\t.salsa_reset(salsa_reset_1), .salsa_start(salsa_start_1), .salsa_shift(salsa_shift_1), .hash_out(hash_1));\n\n\tsalsaengine #(.ADDRBITS(ADDRBITS), .SBITS(SBITS)) S1\n\t\t(.hash_clk(clk_dcm), .reset(salsa_reset_1), .din(salsa_din_1), .dout(salsa_dout_1),\n\t\t.shift(salsa_shift_1), .start(salsa_start_1), .busy(salsa_busy_1), .result(salsa_result_1) );\n\n`ifdef DUALCORE\n\twire gn_match_2;\n\twire [31:0] golden_nonce_2;\n\twire [31:0] hash_2, nonce_out_2;\t\t\t\t// both unused\n\twire salsa_busy_2, salsa_result_2, salsa_reset_2, salsa_start_2, salsa_shift_2;\n\twire [SBITS-1:0] salsa_din_2;\n\twire [SBITS-1:0] salsa_dout_2;\n\n\tpbkdfengine #(.SBITS(SBITS)) P2\n\t\t(.hash_clk(clk_dcm), .pbkdf_clk(clk_dcm), .data1(data1), .data2(data2), .data3(data3), .target(mod_target),\n\t\t.nonce_msb( 4'd8 ), .nonce_out(nonce_out_2), .golden_nonce_out(golden_nonce_2),\n\t\t.golden_nonce_match(gn_match_2), .loadnonce(loadnonce),\n\t\t.salsa_din(salsa_din_2), .salsa_dout(salsa_dout_2), .salsa_busy(salsa_busy_2), .salsa_result(salsa_result_2),\n\t\t.salsa_reset(salsa_reset_2), .salsa_start(salsa_start_2), .salsa_shift(salsa_shift_2), .hash_out(hash_2));\n\n\tsalsaengine #(.ADDRBITS(ADDRBITS), .SBITS(SBITS)) S2\n\t\t(.hash_clk(clk_dcm), .reset(salsa_reset_2), .din(salsa_din_2), .dout(salsa_dout_2),\n\t\t.shift(salsa_shift_2), .start(salsa_start_2), .busy(salsa_busy_2), .result(salsa_result_2) );\n\n\tassign got_ticket1 = gn_match_1;\n\tassign got_ticket2 = gn_match_2;\n\tassign slave_nonces = { golden_nonce_2 , golden_nonce_1 };\n`else\n\t// Single core\n\tassign got_ticket1 = gn_match_1;\n\tassign slave_nonces = golden_nonce_1;\n`endif\n\n\tassign miner_busy = ~ (|nonce_out_1[30:20]);\t// Set idle if nonce > 1M (ignore MSB)\n\n\t//Flasher, this handles dividing down the comm clock by 24bits to blink the clock status LED\n\tflasher #(\n\t\t\t.BITS(CLOCK_FLASH_BITS)\n\t\t) CLK_FLASH (\n\t\t\t.clk(clk_dcm),\n\t\t\t.flash(clock_flash)\n\t\t);\n\t\n\t//Nonce PWM Fader core. This triggers on a new nonce found, flashes to full brightness, then fades out for nonce found LED.\n\tpwm_fade PWM_FADE_NONCE (\n\t\t\t.clk(clk_comm_buf), \n\t\t\t.trigger(|new_nonces), \n\t\t\t.drive(led_nonce_fade)\n\t\t);\t\n\n\t//Serial PWM Fader core. This triggers on a new nonce found, flashes to full brightness, then fades out for nonce found LED.\n\tpwm_fade PWM_FADE_COMM (\n\t\t\t.clk(clk_comm_buf), \n\t\t\t.trigger(~TxD || ~RxD), \n\t\t\t.drive(led_serial_fade)\n\t\t);\t\n\t\n\t// Clock Crossing\n\n`ifdef SIM\t\n\tassign syncstart_mining = reset_a;\t\t\t// Used only for simulation\n`else\n\tassign syncstart_mining = start_mining;\n`endif\n\n\talways@ (posedge clk_dcm)\n\t\tbegin\n\t\t\tif (got_ticket1)\n\t\t\t\tsyncticket1[0] <= ~syncticket1[0];\n`ifdef DUALCORE\n\t\t\tif (got_ticket2)\n\t\t\t\tsyncticket2[0] <= ~syncticket2[0];\n`endif\n\t\t\tsyncloadnonce[3:1] <= syncloadnonce[2:0];\n\t\t\tloadnonce <= (syncloadnonce[3] != syncloadnonce[2]);\n\t\tend\n\n\talways@ (posedge clk_comm_buf)\n\t\tbegin\n\t\t\tsyncticket1[3:1] <= syncticket1[2:0];\n\t\t\tnew_nonces[0] <= (syncticket1[3] != syncticket1[2]);\n`ifdef DUALCORE\n\t\t\tsyncticket2[3:1] <= syncticket2[2:0];\n\t\t\tnew_nonces[1] <= (syncticket2[3] != syncticket2[2]);\n`endif\n\t\tsyncstart_mining_d <= syncstart_mining;\n\t\tif (syncstart_mining & ~syncstart_mining_d)\n\t\t\tsyncloadnonce[0] <= ~ syncloadnonce[0];\n\t\tend\n\nendmodule\n\n"
  },
  {
    "path": "experimental/CM1/hashvoodoo_test.v",
    "content": "`timescale 1ns / 1ps\n//////////////////////////////////////////////////////////////////////////////////\n// HashVoodoo Test Module\n// Paul Mumby 2012\n//////////////////////////////////////////////////////////////////////////////////\n`ifdef SIM\nmodule hashvoodoo_test;\n\n\t// Inputs\n\treg clk_p;\n\treg clk_n;\n\treg comm_clk;\n\treg RxD;\n\treg [3:0] dip;\n\treg reset_a;\n\treg reset_b;\n\treg reset_select;\n\n\t// Outputs\n\twire TxD;\n\twire [3:0] led;\n\n\t// Instantiate the Unit Under Test (UUT)\n\tHASHVOODOO uut (\n\t\t.clk_p(clk_p), \n\t\t.clk_n(clk_n), \n\t\t.clk_comm(comm_clk), \n\t\t.RxD(RxD), \n\t\t.TxD(TxD), \n\t\t.led(led), \n\t\t.dip(dip), \n\t\t.reset_a(reset_a), \n\t\t.reset_b(reset_b), \n\t\t.reset_select(reset_select)\n\t);\n\n\t//Clock Control\n\talways begin\n\t\t#5;\n\t\tclk_p = ~clk_p;\n\t\tclk_n = ~clk_n;\n\t\tcomm_clk = ~comm_clk;\n\tend\n\t\t\n\tinitial begin\n\t\t// Initialize Inputs\n\t\tclk_p = 0;\t\t\t// Becomes clk_dcm\n\t\tclk_n = 1;\t\t\t// Ignored\n\t\tcomm_clk = 0;\n\t\tRxD = 0;\n\t\tdip = 0;\n\t\treset_a = 0;\n\t\treset_b = 0;\n\t\treset_select = 0;\n\n\t\t// Wait 100 ns for global reset to finish\n\t\t#100;\n        \n\t\t// Add stimulus here\n\t\treset_a = 1;\t\t\t// Repurposed in simulation for start_mining flag (positive edge detected)\n\tend\n      \nendmodule\n`endif\n"
  },
  {
    "path": "experimental/CM1/hub_core.v",
    "content": "module hub_core (hash_clk, new_nonces, golden_nonce, serial_send, serial_busy, slave_nonces);\n   parameter SLAVES = 2;\n\n   input hash_clk;\n   \n   input [SLAVES-1:0] new_nonces;\n   input [SLAVES*32-1:0] slave_nonces;\n   output [31:0] \t golden_nonce;\n   output \t\t serial_send;\n   input \t\t serial_busy;\n\n   reg \t\t\t serial_send_reg;\n   assign serial_send = serial_send_reg;\n  \n   // Remember all nonces, even when they come too close together, and\n   // send them whenever the uplink is ready\n   reg [SLAVES-1:0] \tnew_nonces_flag = 0;\n   \n   // Replace the tedious if-else chain for input ports with a\n   // continuously running selector. This may seem slow/inefficient\n   // for a large hub, but it is still insanely faster than the serial\n   // port we are driving. Also, due to simplicity, it should be more\n   // robust for big hubs with fast clocks.\n   reg [$clog2(SLAVES)+1:0] port_counter = 0;\n   reg [SLAVES*32-1:0] \t    slave_nonces_shifted;\n   assign golden_nonce = slave_nonces_shifted[31:0];\n\n   // When sending, mark nonces to be cleared during next clock cycle\n   reg [SLAVES-1:0] \t    clear_nonces;\n   \n   always @(posedge hash_clk)\n     begin\n\t// Raise flags when new nonces appear; lower those that have\n\t// been sent\n\tnew_nonces_flag <= (new_nonces_flag & ~clear_nonces) | new_nonces;\n\n\tif (port_counter == SLAVES-1)\n\t  port_counter <= 0;\n\telse\n\t  port_counter <= port_counter + 1;\n\t\n\t// Send results one at a time, mark to be cleared\n\tif (!serial_busy && new_nonces_flag[port_counter])\n\t  begin\n\t     slave_nonces_shifted <= slave_nonces >> port_counter*32;\n\t     serial_send_reg <= 1;\n\t     clear_nonces[port_counter] <= 1;\n\t  end\n\telse \n\t  begin\n\t     serial_send_reg <= 0;\n\t     clear_nonces <= 0;\n\t  end\n     end\n\nendmodule // hub_core\n"
  },
  {
    "path": "experimental/CM1/main_dcm.v",
    "content": "// file: main_dcm.v\n// \n// (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.\n// \n// This file contains confidential and proprietary information\n// of Xilinx, Inc. and is protected under U.S. and\n// international copyright and other intellectual property\n// laws.\n// \n// DISCLAIMER\n// This disclaimer is not a license and does not grant any\n// rights to the materials distributed herewith. Except as\n// otherwise provided in a valid license issued to you by\n// Xilinx, and to the maximum extent permitted by applicable\n// law: (1) THESE MATERIALS ARE MADE AVAILABLE \"AS IS\" AND\n// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES\n// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING\n// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-\n// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and\n// (2) Xilinx shall not be liable (whether in contract or tort,\n// including negligence, or under any other theory of\n// liability) for any loss or damage of any kind or nature\n// related to, arising under or in connection with these\n// materials, including for any direct, or any indirect,\n// special, incidental, or consequential loss or damage\n// (including loss of data, profits, goodwill, or any type of\n// loss or damage suffered as a result of any action brought\n// by a third party) even if such damage or loss was\n// reasonably foreseeable or Xilinx had been advised of the\n// possibility of the same.\n// \n// CRITICAL APPLICATIONS\n// Xilinx products are not designed or intended to be fail-\n// safe, or for use in any application requiring fail-safe\n// performance, such as life-support or safety devices or\n// systems, Class III medical devices, nuclear facilities,\n// applications related to the deployment of airbags, or any\n// other applications that could lead to death, personal\n// injury, or severe property or environmental damage\n// (individually and collectively, \"Critical\n// Applications\"). Customer assumes the sole risk and\n// liability of any use of Xilinx products in Critical\n// Applications, subject only to applicable laws and\n// regulations governing limitations on product liability.\n// \n// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS\n// PART OF THIS FILE AT ALL TIMES.\n// \n//----------------------------------------------------------------------------\n// User entered comments\n//----------------------------------------------------------------------------\n// None\n//\n//----------------------------------------------------------------------------\n// \"Output    Output      Phase     Duty      Pk-to-Pk        Phase\"\n// \"Clock    Freq (MHz) (degrees) Cycle (%) Jitter (ps)  Error (ps)\"\n//----------------------------------------------------------------------------\n// CLK_OUT1___800.000______0.000_______N/A______205.000________N/A\n//\n//----------------------------------------------------------------------------\n// \"Input Clock   Freq (MHz)    Input Jitter (UI)\"\n//----------------------------------------------------------------------------\n// __primary__________25.000____________0.010\n\n`timescale 1ps/1ps\n\n(* CORE_GENERATION_INFO = \"main_dcm,clk_wiz_v4_1,{component_name=main_dcm,use_phase_alignment=false,use_min_o_jitter=false,use_max_i_jitter=false,use_dyn_phase_shift=false,use_inclk_switchover=false,use_dyn_reconfig=true,feedback_source=FDBK_AUTO,primtype_sel=DCM_CLKGEN,num_out_clk=1,clkin1_period=40.000,clkin2_period=40.000,use_power_down=false,use_reset=true,use_locked=false,use_inclk_stopped=false,use_status=false,use_freeze=false,use_clk_valid=true,feedback_type=SINGLE,clock_mgr_type=MANUAL,manual_override=true}\" *)\nmodule main_dcm\n (// Clock in ports\n  input         CLK_OSC,\n  // Clock out ports\n  output        CLK_HASH,\n  // Dynamic reconfiguration ports\n  input         PROGCLK,\n  input         PROGDATA,\n  input         PROGEN,\n  output        PROGDONE,\n  // Status and control signals\n  input         RESET,\n  output        CLK_VALID\n );\n\n\tparameter DCM_DIVIDER = 10;\t\n\tparameter DCM_MULTIPLIER = 60;\n\n  // Input buffering\n  //------------------------------------\n  BUFG clkin1_buf\n   (.O (clkin1),\n    .I (CLK_OSC));\n\t \n  // Clocking primitive\n  //------------------------------------\n  // Instantiation of the DCM primitive\n  //    * Unused inputs are tied off\n  //    * Unused outputs are labeled unused\n  wire        locked_int;\n  wire [2:1]  status_int;\n  wire        clkfx;\n  wire        clkfx180_unused;\n  wire        clkfx_unused;\t\t\t// KRAMBLE was clkfxdv_unused\n\n  DCM_CLKGEN\n  #(.CLKFXDV_DIVIDE        (4),\t\t\t\t\t// KRAMBLE approx 50Mhz dcm_clk (for nominal 200MHz)\n    .CLKFX_DIVIDE          (DCM_DIVIDER),\n    .CLKFX_MULTIPLY        (DCM_MULTIPLIER),\n    .SPREAD_SPECTRUM       (\"NONE\"),\n    .STARTUP_WAIT          (\"FALSE\"),\n    .CLKIN_PERIOD          (40.000),\n    .CLKFX_MD_MAX          (0.000))\n   dcm_clkgen_inst\n    // Input clock\n   (.CLKIN                 (clkin1),\n    // Output clocks\n    .CLKFX                 (clkfx_unused),\n    .CLKFX180              (clkfx180_unused),\n    .CLKFXDV               (clkfx),\t\t\t\t// KRAMBLE now using divided output\n    // Ports for dynamic reconfiguration\n    .PROGCLK               (PROGCLK),\n    .PROGDATA              (PROGDATA),\n    .PROGEN                (PROGEN),\n    .PROGDONE              (PROGDONE),\n    // Other control and status signals\n    .FREEZEDCM             (1'b0),\n    .LOCKED                (locked_int),\n    .STATUS                (status_int),\n    .RST                   (RESET));\n\n    assign CLK_VALID = ( ( locked_int == 1'b 1 ) && ( status_int[2] == 1'b 0 ) );\n\n  // Output buffering\n  //-----------------------------------\n\n  BUFG clkout1_buf\n   (.O   (CLK_HASH),\n    .I   (clkfx));\n\nendmodule\n"
  },
  {
    "path": "experimental/CM1/pbkdfengine.v",
    "content": "/* pbkdfengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`define ICARUS\t\t\t// Comment this out when using the altera virtual_wire interface in ltcminer.v\n\t\n`timescale 1ns/1ps\n\nmodule pbkdfengine\n\t(hash_clk, pbkdf_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce,\n\t\t\tsalsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift, hash_out);\n\n\tinput hash_clk;\t\t\t// Just drives shift register\n\tinput pbkdf_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\n\toutput reg [31:0] nonce_out;\n\toutput reg [31:0] hash_out;\t\t// Hash value for nonce_out (ztex port)\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] salsa_dout;\n\toutput [SBITS-1:0] salsa_din;\n\n\tinput salsa_busy, salsa_result;\t// NB hash_clk domain\n\toutput salsa_reset;\n\toutput salsa_start;\n\toutput reg salsa_shift = 1'b0;\t// NB hash_clk domain\n\n\treg [4:0]resetcycles = 4'd0;\n\treg reset = 1'b0;\n\tassign salsa_reset = reset;\t\t// Propagate reset to salsaengine\n\n`ifdef WANTCYCLICRESET\t\t\n\treg [23:0]cycresetcount = 24'd0;\n`endif\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\t// Hard code a 31 cycle reset (NB assumes THREADS=16 in salsaengine, else we need more)\n\t\t// NB hash_clk is faster than pbkdf_clk so the salsaengine will actually be initialised well before\n\t\t// this period ends, but keep to 15 for now as simulation uses equal pbkdf and salsa clock speeds.\n\t\tresetcycles <= resetcycles + 1'd1;\n\t\tif (resetcycles == 0)\n\t\t\treset <= 1'b1;\n\t\tif (resetcycles == 31)\n\t\tbegin\n\t\t\treset <= 1'b0;\n\t\t\tresetcycles <= 31;\n\t\tend\n`ifdef WANTCYCLICRESET\t\t\n\t\t// Cyclical reset every 2_500_000 clocks to ensure salsa pipeline does not drift out of sync\n\t\t// This may be unneccessary if we reset every loadnonce\n\t\t// Actually it seems to do more harm than good, so disabled\n\t\tcycresetcount <= cycresetcount + 1'd1;\n\t\tif (cycresetcount == 2_500_000)\t// 10 per second at 25MHz (adjust as neccessary)\n\t\tbegin\n\t\t\tcycresetcount <= 24'd0;\n\t\t\tresetcycles <= 5'd0;\n\t\tend\n`endif\t\t\n\t\t// Reset on loadnonce (the hash results will be junk anyway since data changes, so no loss of shares)\n\t\tif (loadnonce)\n\t\t\tresetcycles <= 5'd0;\n\tend\n\t\n\t`ifndef ICARUS\n\treg [31:0] nonce_previous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\t`endif\n\n\t`ifndef NOMULTICORE\n\t`ifdef SIM\n\t\treg [27:0] nonce_cnt = 28'h318f;\t// Start point for simulation (NB also define SIM in serial.v)\n\t`else\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t`endif\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\treg [31:0] nonce_sr = 32'd0;\t\t// Nonce is shifted to salsaengine for storage/retrieval (hash_clk domain)\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\treg [2:0] nonce_wait = 3'd0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [2:0] blockcnt = 3'd0;\t\t// Takes values 1..5 for block iteration\n\treg [1023:0] Xbuf = 1024'd0;\t// Shared input/output buffer and shift register (hash_clk domain)\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\tassign salsa_din = Xbuf[1023:1024-SBITS];\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\t\n\t// MixOut is little-endian word format to match scrypt.c so convert back to big-endian\n\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] mix;\n\t\tassign mix = Xbuf[`IDX(i)];\t\t// NB MixOut now shares Xbuf since shifted in/out\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\n\t// Interface control. This should be OK provided the threads remain evenly spaced (hence we reset on loadnonce)\n\t\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\treg Clr_SMixOutRdy = 1'b0;\n\twire Clr_SMixInRdy;\n\twire Set_SMixOutRdy;\n\n\treg [4:0]salsa_busy_d = 0;\t\t\t// Sync to pbkdf_clk domain\n\treg [4:0]salsa_result_d = 0;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\t// Sync to pbkdf_clk domain\n\t\tsalsa_busy_d[0] <= salsa_busy;\n\t\tif (salsa_busy & ~ salsa_busy_d[0])\n\t\t\tsalsa_busy_d[1] <= ~ salsa_busy_d[1];\t\t// Toggle on busy going high\n\t\t\n\t\tsalsa_result_d[0] <= salsa_result;\n\t\tif (salsa_result & ~ salsa_result_d[0])\n\t\t\tsalsa_result_d[1] <= ~ salsa_result_d[1];\t// Toggle on result going high\n\tend\n\t\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tsalsa_busy_d[4:2] <= salsa_busy_d[3:1];\n\t\tsalsa_result_d[4:2] <= salsa_result_d[3:1];\n\t\t\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\t\t\t\n\t\t// CARE there is a race with Set_SMixInRdy, Clr_SMixOutRdy which are set in the FSM\n\t\t// Need to assert reset for several cycles to ensure consistency (acutally use 15 since salsaengine needs more)\n\t\tif (reset)\n\t\tbegin\t\t\t\t\t\t\t// Reset takes priority\n\t\t\tSMixInRdy_state <= 1'b0;\n\t\t\tSMixOutRdy_state <= 1'b0;\n\t\tend\n\tend\n\t\n\tassign Clr_SMixInRdy = SMixInRdy_state & (salsa_busy_d[3] ^ salsa_busy_d[4]);\t\t\t// Clear on transition to busy\n\t\n\tassign Set_SMixOutRdy = ~SMixOutRdy_state & (salsa_result_d[3] ^ salsa_result_d[4]);\t// Set on transition to result\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\tassign salsa_start = SMixInRdy;\n\t\t\n\t// Clock crossing flags for shift register control (span pbkdf_clk, hash_clk domains)\n\treg [3:0]Xbuf_load_request = 1'b0;\n\treg [3:0]shift_request =  1'b0;\n\treg [3:0]shift_acknowledge = 1'b0;\n\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz)\n\t\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_NONCE=22, S_SHIFT_IN=41, S_SHIFT_OUT=42,\t\t\t\t// Direction relative to salsa unit\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\treg start_output = 0;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\n\t\tshift_acknowledge[3:1] <= shift_acknowledge[2:0];\t// Clock crossing\n\n\t\t`ifdef ICARUS\n\t\tif (loadnonce)\t\t\t\t// Separate clock domains means comparison is unsafe\n\t\t`else\n\t\tif (loadnonce || (nonce_previous_load != data3[127:96]))\n\t\t`endif\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_previous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\t`ifndef ICARUS\n\t\t\tnonce_previous_load <= data3[127:96];\n\t\t\t`endif\n\t\tend\n\t\t\n\t\tif (reset == 1'b1)\n\t\tbegin\n\t\t\tstate <= S_IDLE;\n\t\t\tstart_output <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tif (SMixOutRdy & ~start_output)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\t// Request shifter to start\n\t\t\t\t\t\tstate <= S_SHIFT_OUT;\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (start_output ||\t// Process output\n\t\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'b0;\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\t\tblockcnt <= 3'd1;\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_sr : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\t\t\n\t\t\t\tS_B6: begin\n\t\t\t\t\t\tkhash <= tx_hash;\t\t// Save temporarily (for Xbuf)\n\n\t\t\t\t\t\tXbuf_load_request[0] <= ~Xbuf_load_request[0];\t// NB also loads nonce_sr\n\n\t\t\t\t\t\tif (blockcnt == 3'd5)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tnonce_wait <= 3'd7;\n\t\t\t\t\t\t\tstate <= S_NONCE;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_NONCE: begin\n\t\t\t\t\t\t// Need to delay a few clocks for Xbuf_load_request to complete\n\t\t\t\t\t\tnonce_wait <= nonce_wait - 1'd1;\n\t\t\t\t\t\tif (nonce_wait == 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 1'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 1'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\n\t\t\t\t\t\t\tstate <= S_SHIFT_IN;\n\t\t\t\t\t\tend\n\t\t\t\t\n\t\t\t\tend\n\t\t\t\tS_SHIFT_IN: begin\t\t\t\t\t\t\t// Shifting from PBKDF2_SHA256 to salsa\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tSet_SMixInRdy <= 1'd1;\t\t\t\t// Flag salsa to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_SHIFT_OUT: begin\t\t\t\t\t\t\t// Shifting from salsa to PBKDF2_SHA256\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'd1;\t\t\t\t// Flag self to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\tnonce_out <= nonce_sr;\t\t\t// Ztex port\n\t\t\t\t\t\thash_out <= tx_hash[255:224];\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_sr;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n\tend\n\n\t// Shift register control - NB hash_clk domain\n\t\n\treg\t[10:0]shift_count = 11'd0;\t// hash_clk domain\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tif (reset)\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b0;\n\t\t\tshift_count <= 11'd0;\n\t\tend\n\n\t\t// Clock crossing logic\n\t\tXbuf_load_request[3:1] <= Xbuf_load_request[2:0];\n\t\tif (Xbuf_load_request[3] != Xbuf_load_request[2])\n\t\tbegin\n\t\t\t// Shift output into X buffer from MSB->LSB\n\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\tXbuf[1023:768] <= khash;\n\n\t\t\tnonce_sr <= nonce;\t// Loaded several times, but of no consequence\n\t\tend\n\t\t\n\t\tshift_request[3:1] <= shift_request[2:0];\n\t\tif (shift_request[3] != shift_request[2])\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b1;\n\t\tend\n\n\t\tif (salsa_shift)\n\t\tbegin\n\t\t\tshift_count <= shift_count + 1'b1;\n\t\t\tXbuf <= { Xbuf[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], salsa_dout };\n\t\tend\n\t\t\n\t\tif (shift_count == (1024+32)/SBITS-1)\n\t\tbegin\n\t\t\tshift_acknowledge[0] = ~shift_acknowledge[0];\n\t\t\tshift_count <= 0;\n\t\t\tsalsa_shift <= 0;\n\t\tend\n\tend\n\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(pbkdf_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\nendmodule"
  },
  {
    "path": "experimental/CM1/pwm_fade.v",
    "content": "// When triggered, turn the output to maximum and start fading to black\n\n// by teknohog\n\nmodule pwm_fade (clk, trigger, drive);\n   input trigger;\n   input clk;\n   output drive;\n\n   //parameter FADE_BITS = 27;\n   parameter LEVEL_BITS = 8;\n\n   // Average block interval in clock cycles is\n   // 2**32 / (clk * 0.5**ll2 * miners) * clk\n   // where (clk * 0.5**ll2 * miners) is the hashrate\n   parameter LOCAL_MINERS = 1;\n   parameter LOOP_LOG2 = 1;\n   //localparam FADE_BITS = 32 + LOOP_LOG2 - $clog2(LOCAL_MINERS);\n\n   // Xilinx ISE 13.2 cannot handle $clog2 in localparam, but it works\n   // in the index\n`define FADE_BITS 26\n   \n   reg [LEVEL_BITS-1:0] pwm_counter;\n   always @(posedge clk) pwm_counter = pwm_counter + 1;\n\n   reg [`FADE_BITS-1:0] fade_counter = 0;\n   always @(posedge clk)\n     if (trigger) fade_counter = 0 - 1;\n     else if (|fade_counter) fade_counter = fade_counter - 1;\n   \n   // For some reason, {FADE_BITS{1}} sets the register to zero, but\n   // 0-1 works. Also, it needs to be explicitly initialized to\n   // zero. Could be just a Nexys2 quirk, as these LEDs are routed to\n   // general I/O pins too.\n     \n   wire [LEVEL_BITS-1:0] level;\n   assign level = fade_counter[`FADE_BITS-1:`FADE_BITS-LEVEL_BITS];\n\n   // With <= we cannot have true zero; with < we cannot have full\n   // brightness. This is a rather fundamental problem, since we need\n   // 256 timeslices to fill the whole, but the choice of \"off\" would\n   // require an extra bit... of course, it is possible to get by\n   // using a little extra logic.\n   assign drive = (pwm_counter < level);\n   \nendmodule\n"
  },
  {
    "path": "experimental/CM1/salsa_slowsixteen.v",
    "content": "/* salsa_slowsixteen.v\n*\n* Copyright (c) 2013 kramble\n* Derived from scrypt.c Copyright 2009 Colin Percival, 2011 ArtForz\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\nmodule salsa (clk, B, Bx, Bo, X0out, Xaddr);\n\n// Latency 16 clock cycles, approx 20nS propagation delay (SLOW!)\n\ninput clk;\n// input feedback;\ninput [511:0]B;\ninput [511:0]Bx;\n// output reg [511:0]Bo;\t// Output is registered\noutput [511:0]Bo;\t\t\t// Output is async\noutput [511:0]X0out;\t\t// Becomes new X0\noutput [9:0] Xaddr;\nwire [9:0] xa1, xa2, xa3, xa4, ya1, ya2, ya3, ya4;\n\nreg [511:0]x1d1, x1d1a;\nreg [511:0]x1d2, x1d2a;\nreg [511:0]x1d3, x1d3a;\nreg [511:0]x1d4, x1d4a;\n\nreg [511:0]Xod1, Xod1a;\nreg [511:0]Xod2, Xod2a;\nreg [511:0]Xod3, Xod3a;\nreg [511:0]Xod4, X0out;\n\nreg [511:0]xxd1, xxd1a;\nreg [511:0]xxd2, xxd2a;\nreg [511:0]xxd3, xxd3a;\nreg [511:0]xxd4, xxd4a;\n\nreg [511:0]yyd1, yyd1a;\nreg [511:0]yyd2, yyd2a;\nreg [511:0]yyd3, yyd3a;\nreg [511:0]yyd4, yyd4a;\n\nwire [511:0]xx;\t\t\t// Initial xor\nwire [511:0]x1;\t\t\t// Salasa core outputs\nwire [511:0]x2;\nwire [511:0]x3;\nwire [511:0]xr;\nwire [511:0]Xo;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsax1 (clk, xx, x1, xa1);\nsalsa_core salsax2 (clk, x1, x2, xa2);\nsalsa_core salsax3 (clk, x2, x3, xa3);\nsalsa_core salsax4 (clk, x3, xr, xa4);\n\nwire [511:0]yy;\t\t\t// Initial xor\nwire [511:0]y1;\t\t\t// Salasa core outputs\nwire [511:0]y2;\nwire [511:0]y3;\nwire [511:0]yr;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsay1 (clk, yy, y1, ya1);\nsalsa_core salsay2 (clk, y1, y2, ya2);\nsalsa_core salsay3 (clk, y2, y3, ya3);\nsalsa_core salsay4 (clk, y3, yr, ya4);\n\nassign Xaddr = yyd4[9:0] + ya4;\n\ngenvar i;\ngenerate\n\tfor (i = 0; i < 16; i = i + 1) begin : XX\n\t\t// Initial XOR. NB this adds to the propagation delay of the first salsa, may want register it.\n\t\tassign xx[`IDX(i)] = B[`IDX(i)] ^ Bx[`IDX(i)];\n\t\tassign Xo[`IDX(i)] = xxd4a[`IDX(i)] + xr[`IDX(i)];\n\t\tassign yy[`IDX(i)] = x1d4a[`IDX(i)] ^ Xo[`IDX(i)];\n\t\tassign Bo[`IDX(i)] = yyd4a[`IDX(i)] + yr[`IDX(i)];\t// Async output\n\tend\nendgenerate\n\nalways @ (posedge clk)\nbegin\n\tx1d1 <= Bx;\n\tx1d1a <= x1d1;\n\tx1d2 <= x1d1a;\n\tx1d2a <= x1d2;\n\tx1d3 <= x1d2a;\n\tx1d3a <= x1d3;\n\tx1d4 <= x1d3a;\n\tx1d4a <= x1d4;\n\tXod1 <= Xo;\n\tXod1a <= Xod1;\n\tXod2 <= Xod1a;\n\tXod2a <= Xod2;\n\tXod3 <= Xod2a;\n\tXod3a <= Xod3;\n\tXod4 <= Xod3a;\n\tX0out <= Xod4;\t// We output this to become new X0\n\n\txxd1 <= xx;\n\txxd1a <= xxd1;\n\txxd2 <= xxd1a;\n\txxd2a <= xxd2;\n\txxd3 <= xxd2a;\n\txxd3a <= xxd3;\n\txxd4 <= xxd3a;\n\txxd4a <= xxd4;\n\n\tyyd1 <= yy;\n\tyyd1a <= yyd1;\n\tyyd2 <= yyd1a;\n\tyyd2a <= yyd2;\n\tyyd3 <= yyd2a;\n\tyyd3a <= yyd3;\n\tyyd4 <= yyd3a;\n\tyyd4a <= yyd4;\n\nend\n\nendmodule\n\nmodule salsa_core (clk, xx, out, Xaddr);\n\ninput clk;\ninput [511:0]xx;\noutput reg [511:0]out;\t\t// Output is registered\noutput [9:0] Xaddr;\t\t\t// Address output unregistered\n\n// This is clunky due to my lack of verilog skills but it works so elegance can come later\n\nwire [31:0]c00;\t\t\t// Column results\nwire [31:0]c01;\nwire [31:0]c02;\nwire [31:0]c03;\nwire [31:0]c04;\nwire [31:0]c05;\nwire [31:0]c06;\nwire [31:0]c07;\nwire [31:0]c08;\nwire [31:0]c09;\nwire [31:0]c10;\nwire [31:0]c11;\nwire [31:0]c12;\nwire [31:0]c13;\nwire [31:0]c14;\nwire [31:0]c15;\n\nwire [31:0]r00;\t\t\t// Row results\nwire [31:0]r01;\nwire [31:0]r02;\nwire [31:0]r03;\nwire [31:0]r04;\nwire [31:0]r05;\nwire [31:0]r06;\nwire [31:0]r07;\nwire [31:0]r08;\nwire [31:0]r09;\nwire [31:0]r10;\nwire [31:0]r11;\nwire [31:0]r12;\nwire [31:0]r13;\nwire [31:0]r14;\nwire [31:0]r15;\n\nwire [31:0]c00s;\t\t\t// Column sums\nwire [31:0]c01s;\nwire [31:0]c02s;\nwire [31:0]c03s;\nwire [31:0]c04s;\nwire [31:0]c05s;\nwire [31:0]c06s;\nwire [31:0]c07s;\nwire [31:0]c08s;\nwire [31:0]c09s;\nwire [31:0]c10s;\nwire [31:0]c11s;\nwire [31:0]c12s;\nwire [31:0]c13s;\nwire [31:0]c14s;\nwire [31:0]c15s;\n\nwire [31:0]r00s;\t\t\t// Row sums\nwire [31:0]r01s;\nwire [31:0]r02s;\nwire [31:0]r03s;\nwire [31:0]r04s;\nwire [31:0]r05s;\nwire [31:0]r06s;\nwire [31:0]r07s;\nwire [31:0]r08s;\nwire [31:0]r09s;\nwire [31:0]r10s;\nwire [31:0]r11s;\nwire [31:0]r12s;\nwire [31:0]r13s;\nwire [31:0]r14s;\nwire [31:0]r15s;\n\nreg [31:0]c00d;\t\t\t// Column results registered\nreg [31:0]c01d;\nreg [31:0]c02d;\nreg [31:0]c03d;\nreg [31:0]c04d;\nreg [31:0]c05d;\nreg [31:0]c06d;\nreg [31:0]c07d;\nreg [31:0]c08d;\nreg [31:0]c09d;\nreg [31:0]c10d;\nreg [31:0]c11d;\nreg [31:0]c12d;\nreg [31:0]c13d;\nreg [31:0]c14d;\nreg [31:0]c15d;\n\n/* From scrypt.c\n\n#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))\n\tfor (i = 0; i < 8; i += 2) {\n\t\t// Operate on columns\n\t\tx04 ^= R(x00+x12, 7);\tx09 ^= R(x05+x01, 7);\tx14 ^= R(x10+x06, 7);\tx03 ^= R(x15+x11, 7);\n\t\tx08 ^= R(x04+x00, 9);\tx13 ^= R(x09+x05, 9);\tx02 ^= R(x14+x10, 9);\tx07 ^= R(x03+x15, 9);\n\t\tx12 ^= R(x08+x04,13);\tx01 ^= R(x13+x09,13);\tx06 ^= R(x02+x14,13);\tx11 ^= R(x07+x03,13);\n\t\tx00 ^= R(x12+x08,18);\tx05 ^= R(x01+x13,18);\tx10 ^= R(x06+x02,18);\tx15 ^= R(x11+x07,18);\n\n\t\t// Operate on rows\n\t\tx01 ^= R(x00+x03, 7);\tx06 ^= R(x05+x04, 7);\tx11 ^= R(x10+x09, 7);\tx12 ^= R(x15+x14, 7);\n\t\tx02 ^= R(x01+x00, 9);\tx07 ^= R(x06+x05, 9);\tx08 ^= R(x11+x10, 9);\tx13 ^= R(x12+x15, 9);\n\t\tx03 ^= R(x02+x01,13);\tx04 ^= R(x07+x06,13);\tx09 ^= R(x08+x11,13);\tx14 ^= R(x13+x12,13);\n\t\tx00 ^= R(x03+x02,18);\tx05 ^= R(x04+x07,18);\tx10 ^= R(x09+x08,18);\tx15 ^= R(x14+x13,18);\n\t}\n*/\n\n// cols\n\nassign c04s = xx[`IDX(0)] + xx[`IDX(12)];\nassign c04 = xx[`IDX(4)] ^ { c04s[24:0], c04s[31:25] };\nassign c09s = xx[`IDX(5)] + xx[`IDX(1)];\nassign c09 = xx[`IDX(9)] ^ { c09s[24:0], c09s[31:25] };\nassign c14s = xx[`IDX(10)] + xx[`IDX(6)];\nassign c14 = xx[`IDX(14)] ^ { c14s[24:0], c14s[31:25] };\nassign c03s = xx[`IDX(15)] + xx[`IDX(11)];\nassign c03 = xx[`IDX(03)] ^ { c03s[24:0], c03s[31:25] };\n\nassign c08s = c04 + xx[`IDX(0)];\nassign c08 = xx[`IDX(8)] ^ { c08s[22:0], c08s[31:23] };\nassign c13s = c09 + xx[`IDX(5)];\nassign c13 = xx[`IDX(13)] ^ { c13s[22:0], c13s[31:23] };\nassign c02s = c14 + xx[`IDX(10)];\nassign c02 = xx[`IDX(2)] ^ { c02s[22:0], c02s[31:23] };\nassign c07s = c03 + xx[`IDX(15)];\nassign c07 = xx[`IDX(7)] ^ { c07s[22:0], c07s[31:23] };\n\nassign c12s = c08 + c04;\nassign c12 = xx[`IDX(12)] ^ { c12s[18:0], c12s[31:19] };\nassign c01s = c13 + c09;\nassign c01 = xx[`IDX(1)] ^ { c01s[18:0], c01s[31:19] };\nassign c06s = c02 + c14;\nassign c06 = xx[`IDX(6)] ^ { c06s[18:0], c06s[31:19] };\nassign c11s = c07 + c03;\nassign c11 = xx[`IDX(11)] ^ { c11s[18:0], c11s[31:19] };\n\nassign c00s = c12 + c08;\nassign c00 = xx[`IDX(0)] ^ { c00s[13:0], c00s[31:14] };\nassign c05s = c01 + c13;\nassign c05 = xx[`IDX(5)] ^ { c05s[13:0], c05s[31:14] };\nassign c10s = c06 + c02;\nassign c10 = xx[`IDX(10)] ^ { c10s[13:0], c10s[31:14] };\nassign c15s = c11 + c07;\nassign c15 = xx[`IDX(15)] ^ { c15s[13:0], c15s[31:14] };\n\n// rows\n\nassign r01s = c00d + c03d;\nassign r01 = c01d ^ { r01s[24:0], r01s[31:25] };\nassign r06s = c05d + c04d;\nassign r06 = c06d ^ { r06s[24:0], r06s[31:25] };\nassign r11s = c10d + c09d;\nassign r11 = c11d ^ { r11s[24:0], r11s[31:25] };\nassign r12s = c15d + c14d;\nassign r12 = c12d ^ { r12s[24:0], r12s[31:25] };\n\nassign r02s = r01 + c00d;\nassign r02 = c02d ^ { r02s[22:0], r02s[31:23] };\nassign r07s = r06 + c05d;\nassign r07 = c07d ^ { r07s[22:0], r07s[31:23] };\nassign r08s = r11 + c10d;\nassign r08 = c08d ^ { r08s[22:0], r08s[31:23] };\nassign r13s = r12 + c15d;\nassign r13 = c13d ^ { r13s[22:0], r13s[31:23] };\n\nassign r03s = r02 + r01;\nassign r03 = c03d ^ { r03s[18:0], r03s[31:19] };\nassign r04s = r07 + r06;\nassign r04 = c04d ^ { r04s[18:0], r04s[31:19] };\nassign r09s = r08 + r11;\nassign r09 = c09d ^ { r09s[18:0], r09s[31:19] };\nassign r14s = r13 + r12;\nassign r14 = c14d ^ { r14s[18:0], r14s[31:19] };\n\nassign r00s = r03 + r02;\nassign r00 = c00d ^ { r00s[13:0], r00s[31:14] };\nassign r05s = r04 + r07;\nassign r05 = c05d ^ { r05s[13:0], r05s[31:14] };\nassign r10s = r09 + r08;\nassign r10 = c10d ^ { r10s[13:0], r10s[31:14] };\nassign r15s = r14 + r13;\nassign r15 = c15d ^ { r15s[13:0], r15s[31:14] };\n\nwire [511:0]xo;\t\t\t// Rename row results\nassign xo = { r15, r14, r13, r12, r11, r10, r09, r08, r07, r06, r05, r04, r03, r02, r01, r00 };\n\nassign Xaddr = xo[9:0];\t// Unregistered output\n\nalways @ (posedge clk)\nbegin\n\tc00d <= c00;\n\tc01d <= c01;\n\tc02d <= c02;\n\tc03d <= c03;\n\tc04d <= c04;\n\tc05d <= c05;\n\tc06d <= c06;\n\tc07d <= c07;\n\tc08d <= c08;\n\tc09d <= c09;\n\tc10d <= c10;\n\tc11d <= c11;\n\tc12d <= c12;\n\tc13d <= c13;\n\tc14d <= c14;\n\tc15d <= c15;\n\tout <= xo;\t\t// Registered output\nend\n\nendmodule\n"
  },
  {
    "path": "experimental/CM1/salsaengine.v",
    "content": "/* salsaengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n// NB HALFRAM no longer applies, configure via parameters ADDRBITS, THREADS\n\n// Bracket this config option in SIM so we don't accidentally leave it set in a live build\n`ifdef SIM\n//`define ONETHREAD\t// Start one thread only (for SIMULATION less confusing and faster startup)\n`endif\n\n`timescale 1ns/1ps\n\nmodule salsaengine (hash_clk, reset, din, dout, shift, start, busy, result );\n\n\n\tinput hash_clk;\n\tinput reset;\t// NB pbkdf_clk domain (need a long reset (at least THREADS+4) to initialize correctly, this is done in pbkdfengine (15 cycles)\n\tinput shift;\n\tinput start;\t// NB pbkdf_clk domain\n\toutput busy;\n\toutput reg result = 1'b0;\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] din;\n\toutput [SBITS-1:0] dout;\n\n\t// Configure ADDRBITS to allocate RAM for core (automatically sets LOOKAHEAD_GAP)\n\t// NB do not use ADDRBITS > 13 for THREADS=8 since this corresponds to more than a full scratchpad\n\n\t// These settings are now overriden in ltcminer_icarus.v determined by LOCAL_MINERS ...\n\t// parameter ADDRBITS = 13;\t// 8MBit RAM allocated to core, full scratchpad (will not fit LX150)\n\tparameter ADDRBITS = 12;\t// 4MBit RAM allocated to core, half scratchpad\n\t// parameter ADDRBITS = 11;\t// 2MBit RAM allocated to core, quarter scratchpad\n\t// parameter ADDRBITS = 10;\t// 1MBit RAM allocated to core, eighth scratchpad\n\n\t// Do not change THREADS - this must match the salsa pipeline (code is untested for other values)\n\tparameter THREADS = 16;\t\t// NB Phase has THREADS+1 cycles\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n\tparameter THREADS_BITS = clog2(THREADS);\n\t\n\t// Workaround for range-reversal error in inactive code when ADDRBITS=13\n\tparameter ADDRBITSX = (ADDRBITS == 13) ? ADDRBITS-1 : ADDRBITS;\n\n\treg [THREADS_BITS:0]phase = 0;\n\treg [THREADS_BITS:0]phase_d = THREADS+1;\n\treg reset_d=0, fsmreset=0, start_d=0, fsmstart=0;\n\n\talways @ (posedge hash_clk)\t\t// Phase control and sync\n\tbegin\n\t\tphase <= (phase == THREADS) ? 0 : phase + 1;\n\t\tphase_d <= phase;\n\t\treset_d <= reset;\t\t\t// Synchronise to hash_clk domain\n\t\tfsmreset <= reset_d;\n\t\tstart_d <= start;\n\t\tfsmstart <= start_d;\n\tend\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\tparameter XSnull = 0, XSload = 1, XSmix = 2, XSram = 4;\t\t\t// One-hot since these map directly to mux contrls\n\treg [2:0] XCtl = XSnull;\n\n\tparameter R_IDLE=0, R_START=1, R_WRITE=2, R_MIX=3, R_INT=4, R_WAIT=5;\n\treg [2:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs\n\treg addrsourceMix = 1'b0;\n\treg datasourceLoad = 1'b0;\n\treg addrsourceSave = 1'b0;\n\treg resultsourceRam = 1'b0;\n\treg xoren = 1'b1;\n\treg [THREADS_BITS+1:0] intcycles = 0;\t// Number of interpolation cycles required ... How many do we need? Say THREADS_BITS+1\n\n\twire [511:0] Xmix;\n\treg [511:0] X0;\n\treg [511:0] X1;\n\twire [511:0] X0in;\n\twire [511:0] X1in;\n\twire [511:0] X0out;\n\treg [1023:0] salsaShiftReg;\n\treg [31:0] nonce_sr;\t\t\t// In series with salsaShiftReg\n\tassign dout = salsaShiftReg[1023:1024-SBITS];\n\n\t// sstate is implemented in ram (alternatively could use a rotating shift register)\n\treg [THREADS_BITS+30:0] sstate [THREADS-1:0];\t\t// NB initialized via a long reset (see pbkdfengine)\n\t// List components of sstate here for ease of maintenance ...\n\twire [2:0] mstate_in;\n\twire [10:0] cycle_in;\n\twire [9:0] writeaddr_in;\n\twire doneROM_in;\n\twire addrsourceMix_in;\n\twire addrsourceSave_in;\n\twire [THREADS_BITS+1:0] intcycles_in;\t\t\t\t// How many do we need? Say THREADS_BITS+1\n\n\twire [9:0] writeaddr_next = writeaddr_in + 10'd1;\n\n\treg [31:0] snonce [THREADS-1:0];\t\t\t\t\t// Nonce store. Note bidirectional loading below, this will either implement\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// as registers or dual-port ram, so do NOT integrate with sstate.\n\t\n\t// NB no busy_in or result_in as these flag are NOT saved on a per-thread basis\n\n\t// Convert salsaShiftReg to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = salsaShiftReg[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\tend\n\tendgenerate\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of RAM size\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\twire [9:0] Xaddr;\n\twire [ADDRBITS-1:0]rd_addr;\n\twire [ADDRBITS-1:0]wr_addr1;\n\twire [ADDRBITS-1:0]wr_addr2;\n\twire [ADDRBITS-1:0]wr_addr3;\n\twire [ADDRBITS-1:0]wr_addr4;\n\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\t(* S = \"TRUE\" *) reg ram_wren = 1'b0;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\t// Top ram address is reserved for X0Save/X1save, so adjust\n\t\n\twire [15:0] memtop = 16'hfffe;\t// One less than the top memory location (per THREAD bank)\n\t\n\twire [ADDRBITS-THREADS_BITS-1:0] adj_addr;\n\n\tif (ADDRBITS < 13)\n\t\tassign adj_addr = (Xaddr[9:THREADS_BITS+10-ADDRBITS] == memtop[9:THREADS_BITS+10-ADDRBITS]) ?\n\t\t\t\t\t\t\tmemtop[ADDRBITS-THREADS_BITS-1:0] : Xaddr[9:THREADS_BITS+10-ADDRBITS];\n\telse\n\t\tassign adj_addr = Xaddr;\n\t\n\twire [THREADS_BITS-1:0] phase_addr;\n\tassign phase_addr = phase[THREADS_BITS-1:0];\n\n\t// TODO can we remove the +1 and adjust the wr_addr to use the same prefix via phase_d?\n\tassign rd_addr = { phase_addr+1, addrsourceSave_in ? memtop[ADDRBITS-THREADS_BITS:1] : adj_addr };\t// LSB are ignored\n\t\t\n\twire [9:0] writeaddr_adj = addrsourceMix ? memtop[10:1] : writeaddr;\n\t\n\tassign wr_addr1 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\tassign wr_addr2 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\tassign wr_addr3 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\tassign wr_addr4 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\n\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_1 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_2 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_3 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_4 = 0;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr1 = rd_addr | rd_addr_z_1;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr2 = rd_addr | rd_addr_z_2;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr3 = rd_addr | rd_addr_z_3;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr4 = rd_addr | rd_addr_z_4;\n\t\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (rd_addr1, wr_addr1, ram_clk, ram1_din, ram_wren, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (rd_addr2, wr_addr2, ram_clk, ram2_din, ram_wren, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (rd_addr3, wr_addr3, ram_clk, ram3_din, ram_wren, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (rd_addr4, wr_addr4, ram_clk, ram4_din, ram_wren, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = datasourceLoad ? X : { Xmix, X0out};\t// Registered input\n\t\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, X0, X1, Xmix, X0out, Xaddr);\n\n\t// Main multiplexer\n\twire [511:0] Zbits;\n\tassign Zbits = {512{xoren}};\t\t// xoren enables xor from ram (else we load from ram)\n\t\n\t// With luck the synthesizer will interpret this correctly as one-hot control ...\n\n\t// DEBUG using default state of 0 for XSnull so as to show up issues with preserved values (previously held value X0/X1)\n\t// assign X0in = (XCtl==XSmix) ? X0out : (XCtl==XSram) ? (X0out & Zbits) ^ ramout[511:0] : (XCtl==XSload) ? X[511:0] : 0;\n\t// assign X1in = (XCtl==XSmix) ? Xmix : (XCtl==XSram) ? (Xmix & Zbits) ^ ramout[1023:512] : (XCtl==XSload) ? X[1023:512] : 0;\n\t\n\t// Now using explicit control signals (rather than relying on synthesizer to map correctly)\n\t// XSMix is now the default (XSnull is unused as this mapped onto zero in the DEBUG version above) - TODO amend FSM accordingly\n\tassign X0in =  XCtl[2] ? (X0out & Zbits) ^ ramout[511:0] : XCtl[0] ? X[511:0] : X0out;\n\tassign X1in =  XCtl[2] ? (Xmix & Zbits) ^ ramout[1023:512] : XCtl[0] ? X[1023:512] : Xmix;\n\n\t// Salsa FSM - TODO may want to move this into a separate function (for floorplanning), see hashvariant-C\n\n\t// Hold separate state for each thread (a bit of a kludge to avoid rewriting FSM from scratch)\n\t// NB must ensure shift and result do NOT overlap by carefully controlling timing of start signal\n\t// NB Phase has THREADS+1 cycles, but we do not save the state for (phase==THREADS) as it is never active\n\n\tassign { mstate_in, writeaddr_in, cycle_in, doneROM_in, addrsourceMix_in, addrsourceSave_in, intcycles_in} =\n\t\t\t\t(phase == THREADS ) ? 0 : sstate[phase];\t\n\t\n\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\n\treg busy_flag = 1'b0;\n\t\n`ifdef ONETHREAD\n\t// TEST CONTROLLER ... just allow a single thread to run (busy is currently a common flag)\n\t// NB the thread automatically restarts after it completes, so its a slight misnomer to say it starts once.\n\treg start_once = 1'b0;\n\twire start_flag;\n\tassign start_flag = fsmstart & ~start_once;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine\n`else\n\t// NB start_flag only has effect when a thread is at R_IDLE, ie after reset, normally a thread will automatically\n\t// restart on completion. We need to spread the R_IDLE starts evenly to ensure proper ooperation. NB the pbkdf\n\t// engine requires busy and result, but this  looks alter itself in the salsa FSM, even though these are global\n\t// flags. Reset periodically (on loadnonce in pbkdfengine) to ensure it stays in sync.\n\treg [15:0] start_count = 0;\n\t// TODO automatic configuration (currently assumes THREADS 8 or 16, and ADDRBITS 12,11,10 calculated as follows...)\n\t// For THREADS=8, lookup_gap=2 salsa takes on average 9*(1024+(1024*1.5)) = 23040 clocks, generically 9*1024*(lookup_gap/2+1.5)\n\t// For THREADS=16, use 17*1024*(lookup_gap/2+1.5), where lookupgap is double that for THREADS=8\n\tparameter START_INTERVAL = (THREADS==16) ?\t((ADDRBITS==12) ? 60928 : (ADDRBITS==11) ? 95744 : 165376) / THREADS :\t// 16 threads\n\t\t\t\t\t\t\t\t\t\t\t\t((ADDRBITS==12) ? 23040 : (ADDRBITS==11) ? 36864 :  50688) / THREADS ;\t//  8 threads\n\treg start_flag = 1'b0;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine - this will toggle on transtion through R_START\n`endif\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tX0 <= X0in;\n\t\tX1 <= X1in;\n\t\t\n\t\tif (phase_d != THREADS)\n\t\t\tsstate[phase_d] <= fsmreset ? 0 : { mstate, writeaddr, cycle, doneROM, addrsourceMix, addrsourceSave, intcycles };\n\n\t\tmstate <= mstate_in;\t\t// Set defaults (overridden below as necessary)\n\t\twriteaddr <= writeaddr_in;\n\t\tcycle <= cycle_in;\n\t\tintcycles <= intcycles_in;\n\t\tdoneROM <= doneROM_in;\n\t\taddrsourceMix <= addrsourceMix_in;\n\t\taddrsourceSave <= addrsourceSave_in;\t\t// Overwritten below, but addrsourceSave_in is used above\n\t\t\n\t\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\trd_addr_z_1 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_2 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_3 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_4 <= {ADDRBITS{fsmreset}};\n\t\t\n\t\tXCtl <= XSnull;\t\t\t\t// Default states\n\t\taddrsourceSave <= 0;\t\t// NB addrsourceSave_in is the active control so this DOES need to be in sstate\n\t\tdatasourceLoad <= 0;\t\t// Does not need to be saved in sstate\n\t\tresultsourceRam <= 0;\t\t// Does not need to be saved in sstate\n\t\tram_wren <= 0;\n\t\txoren <= 1;\n\t\t\n\t\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\t\t`ifdef ONETHREAD\n\t\tif (fsmstart && phase!=THREADS)\n\t\t\tstart_once <= 1'b1;\n\t\tif (fsmreset)\n\t\t\tstart_once <= 1'b0;\n\t\t`else\n\t\tstart_count <= start_count + 1;\n\t\t// start_flag <= 1'b0;\t\t\t// Done below when we transition out of R_IDLE\n\t\tif (fsmreset || start_count == START_INTERVAL)\n\t\tbegin\n\t\t\tstart_count <= 0;\n\t\t\tif (~fsmreset && fsmstart)\n\t\t\t\tstart_flag <= 1'b1;\n\t\tend\n\t\t`endif\n\t\t\n\t\t// Could use explicit mux for this ...\n\t\tif (shift)\n\t\tbegin\n\t\t\tsalsaShiftReg <= { salsaShiftReg[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], din};\n\t\tend\n\t\telse\n\t\tif (XCtl==XSload && phase_d != THREADS)\t\t// Set at end of previous hash - this is executed regardless of phase\t\t\n\t\tbegin\n\t\t\tsalsaShiftReg <= resultsourceRam ? ramout : { Xmix, X0out };\t// Simultaneously with XSload\n\t\t\tnonce_sr <= snonce[phase_d];\t\t\t\t\t\t\t\t\t// NB bidirectional load\n\t\t\tsnonce[phase_d] <= nonce_sr;\n\t\tend\n\t\t\n\t\tif (fsmreset == 1'b1)\n\t\tbegin\n\t\t\tmstate <= R_IDLE;\t\t// This will propagate to all sstate slots as we hold reset for 10 cycles\n\t\t\tbusy_flag <= 1'b0;\n\t\t\tresult <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate_in)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\t// R_IDLE only applies after reset. Normally each thread will reenter at S_START and\n\t\t\t\t\t// assumes that input data is waiting (this relies on the threads being started evenly,\n\t\t\t\t\t// hence the interface FSM at the top of this file)\n\t\t\t\t\tif (phase!=THREADS && start_flag)\t// Ensure (phase==THREADS) slot is never active\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSload;\t\t\t// First time only (normally done at end of previous salsa cycle=1023)\n\t\t\t\t\t\t`ifndef ONETHREAD\n\t\t\t\t\t\t\tstart_flag <= 1'b0;\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t\t// Toggle the busy flag low to ack pbkdfengine (its usually already set\n\t\t\t\t\t\t\t\t\t\t\t\t// since other threads are running)\n\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\tdatasourceLoad <= 1'b1;\n\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tmstate <= R_START;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_START: begin\t\t\t\t\t\t// Reentry point after thread completion. ASSUMES new data is ready.\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\t\twriteaddr <= writeaddr_next;\n\t\t\t\t\t\tcycle <= 0;\n\t\t\t\t\t\tif (ADDRBITS == 13)\n\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Full scratchpad needs to write to addr=001 next cycle\n\t\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\t\tbusy_flag <= 1'b1;\n\t\t\t\t\t\tresult <= 1'b0;\n\t\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\t\tend\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\twriteaddr <= writeaddr_next;\n\t\t\t\t\tif (writeaddr_in==1022)\n\t\t\t\t\t\tdoneROM <= 1'b1;\t\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\telse\n\t\t\t\t\tif (~doneROM_in)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\t\tram_wren <= ~|writeaddr_next[THREADS_BITS+9-ADDRBITSX:0];\t// Only write non-interpolated addresses\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\tend\n\t\t\t\t\t\n\t\t\t\t\tif (doneROM_in)\n\t\t\t\t\tbegin\n\t\t\t\t\t\taddrsourceMix <= 1'b1;\t\t// Remains set for duration of R_MIX\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t// Need this to cover the case of the initial read being interpolated\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_MIX\n\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\tif ( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:THREADS_BITS+10-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr[THREADS_BITS+9-ADDRBITSX:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[THREADS_BITS+9-ADDRBITSX:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\tcycle <= cycle_in + 11'd1;\n\t\t\t\t\tif (cycle_in==1023)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t// Will hold at 0 for 9 clocks until set at R_START\n\t\t\t\t\t\tif (fsmstart)\t\t\t// Check data input is ready\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXCtl <= XSload;\t\t// Initial load else we overwrite input NB This is\n\t\t\t\t\t\t\t\t\t\t\t\t// executed on the next cycle, regardless of phase\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\tmstate <= R_START;\t\t// Restart immediately\n\t\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\t\tdatasourceLoad <= 1'b1;\n\t\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// mstate <= R_IDLE;\t\t// Wait for start_flag\n\t\t\t\t\t\t\tmstate <= R_WAIT;\n\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Save result\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_WRITE\n\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\tif ( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:THREADS_BITS+10-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr[THREADS_BITS+9-ADDRBITSX:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[THREADS_BITS+9-ADDRBITSX:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tR_WAIT: begin\n\t\t\t\t\t\tif (fsmstart)\t\t\t// Check data input is ready\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXCtl <= XSload;\t\t// Initial load else we overwrite input NB This is\n\t\t\t\t\t\t\t\t\t\t\t\t// executed on the next cycle, regardless of phase\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\tmstate <= R_START;\t\t// Restart immediately\n\t\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\t\tdatasourceLoad <= 1'b1;\n\t\t\t\t\t\t\tresultsourceRam <= 1'b1;\n\t\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\tend\n\t\t\t\t\n\t\t\t\tR_INT: begin\n\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\tintcycles <= intcycles_in - 1;\n\t\t\t\t\tif (intcycles_in==2)\n\t\t\t\t\t\taddrsourceSave <= 1'b1;\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\tif (intcycles_in==1)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Setup to XOR from saved X0/X1 in ram at next cycle\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\tend\n\t\t\t\t\t// Else mstate remains at R_INT so we continue interpolating\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (mstate==R_MIX)\n\t\t$display (\"phase %d cycle %d Xmix %08x\\n\", phase, cycle-1, Xmix[511:480]);\n`endif\n\tend\t// always @(posedge hash_clk)\nendmodule"
  },
  {
    "path": "experimental/CM1/serial_core.v",
    "content": "`timescale 1ns / 1ps\n//////////////////////////////////////////////////////////////////////////////////\n// New Serial Core\n// For Enterpoint Cairnsmore1 Icarus Derived Bitstream\n// By Paul Mumby\n// Licensed Under GNU GPL V3\n//////////////////////////////////////////////////////////////////////////////////\nmodule serial_core #(parameter CLOCK=25000000, BAUD=57600, SAMPLE_POINT=8)(\n\tclk,\n\trx,\n\ttx,\n\trx_ready,\n\ttx_ready,\n\tdata1,\n\tdata2,\n\tdata3,\n\tword,\n\ttx_busy,\n\trx_busy\n\t);\n\n\t// IO Declaration\n\t//===================================================\n\tinput clk;\n\tinput rx;\n\toutput tx;\n\toutput rx_ready;\n\tinput tx_ready;\t\n   output [255:0] data1;\n   output [255:0] data2;\n   output [127:0] data3;\n\tinput [31:0] word;\n\toutput tx_busy;\n\toutput rx_busy;\n\t\n\t//Wire & Register Declaration\n\t//===================================================\n\treg uart_tx_ready = 0;\n\twire uart_rx_ready;\n\twire uart_tx_busy;\n\twire uart_rx_busy;\n\twire uart_error;\n\treg [7:0] uart_tx_byte;\n\twire [7:0] uart_rx_byte;\n   reg [3:0] tx_mux_state = 4'b0000;\n\treg [31:0] tx_word_copy;\n`ifdef SIM\n\t// 76 byte protocol excludes nonce\nreg [607:0] rx_input_buffer = {\n\t\t\t96'h7e71441b141fe951b2b0c7df,\n\t\t\t256'hc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af755756,\n\t\t\t256'h18e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000\n\t\t\t};\n`else\n   reg [607:0] rx_input_buffer;\n`endif\n\n\t//Module Instantiation\n\t//===================================================\n\twire unused_rx_error;\n\t\n\tuart #(.CLOCK(CLOCK),.BAUD(BAUD),.SAMPLE_POINT(SAMPLE_POINT)) UART_CORE (\n\t\t.clk(clk),\n\t\t.rx_pin(rx),\n\t\t.tx_pin(tx),\n\t\t.tx_start(uart_tx_ready),\n\t\t.rx_data_ready(uart_rx_ready),\n\t\t.rx_busy(uart_rx_busy),\n\t\t.tx_busy(uart_tx_busy),\n\t\t.tx_byte(uart_tx_byte),\n\t\t.rx_byte(uart_rx_byte),\n\t\t.rx_error(unused_rx_error)\n\t\t);\n\n\t//Assignments\n\t//===================================================\n   assign tx_busy = (|tx_mux_state);\n`ifdef SIM\n\t// 76 byte protocol excludes nonce\n\tassign data3 = { 32'h0000318f, rx_input_buffer[607:512] };\t// Load test nonce (match at ~1042uS)\n`else\n\tassign data3 = { 32'd0, rx_input_buffer[607:512] };\t\t\t// Load zero nonce\n`endif\n   assign data2 = rx_input_buffer[511:256];\n   assign data1 = rx_input_buffer[255:0];\n   assign rx_ready = uart_rx_ready;\n\n\t//Logic\n\t//===================================================\n\t\n\t//TX Handler\n\talways @(posedge clk)\n\tbegin\n\t\tif (!tx_busy && tx_ready)\n\t\t  begin\n\t\t\t  tx_mux_state <= 4'b1000;\n\t\t\t  tx_word_copy <= word;\n\t\t  end  \n\t\telse if (tx_mux_state[3] && ~tx_mux_state[0] && !uart_tx_busy)\n\t\t  begin\n\t\t\t  uart_tx_ready <= 1;\n\t\t\t  tx_mux_state <= tx_mux_state + 1;\n\t\t\t  uart_tx_byte <= tx_word_copy[31:24];\n\t\t\t  tx_word_copy <= (tx_word_copy << 8);\n\t\t  end\n\t\telse if (tx_mux_state[3] && tx_mux_state[0])\n\t\t  begin\n\t\t\t  uart_tx_ready <= 0;\n\t\t\t  if (!uart_tx_busy) tx_mux_state <= tx_mux_state + 1;\n\t\t  end\n\tend\n\t\n\t//RX Handler\n\talways @(posedge clk)\n\tbegin\n\t\tif(uart_rx_ready)\n\t\t\tbegin\n\t\t\t\trx_input_buffer <= rx_input_buffer << 8;\n\t\t\t\trx_input_buffer[7:0] <= uart_rx_byte;\n\t\t\tend\n\t\telse\n\t\t\trx_input_buffer <= rx_input_buffer;\n\tend\n\t\n\nendmodule\n"
  },
  {
    "path": "experimental/CM1/sha-256-functions.v",
    "content": "/*\n*\n* Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n*\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n\n`timescale 1ns/1ps\n\nmodule e0 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y = {x[1:0],x[31:2]} ^ {x[12:0],x[31:13]} ^ {x[21:0],x[31:22]};\n\nendmodule\n\n\nmodule e1 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y = {x[5:0],x[31:6]} ^ {x[10:0],x[31:11]} ^ {x[24:0],x[31:25]};\n\nendmodule\n\n\nmodule ch (x, y, z, o);\n\n\tinput [31:0] x, y, z;\n\toutput [31:0] o;\n\n\tassign o = z ^ (x & (y ^ z));\n\nendmodule\n\n\nmodule maj (x, y, z, o);\n\n\tinput [31:0] x, y, z;\n\toutput [31:0] o;\n\n\tassign o = (x & y) | (z & (x | y));\n\nendmodule\n\n\nmodule s0 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y[31:29] = x[6:4] ^ x[17:15];\n\tassign y[28:0] = {x[3:0], x[31:7]} ^ {x[14:0],x[31:18]} ^ x[31:3];\n\nendmodule\n\n\nmodule s1 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y[31:22] = x[16:7] ^ x[18:9];\n\tassign y[21:0] = {x[6:0],x[31:17]} ^ {x[8:0],x[31:19]} ^ x[31:10];\n\nendmodule\n\n\n"
  },
  {
    "path": "experimental/CM1/sha256_transform.v",
    "content": "/*\n*\n* Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n*\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n\n`timescale 1ns/1ps\n\n// A quick define to help index 32-bit words inside a larger register.\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\n// Perform a SHA-256 transformation on the given 512-bit data, and 256-bit\n// initial state,\n// Outputs one 256-bit hash every LOOP cycle(s).\n//\n// The LOOP parameter determines both the size and speed of this module.\n// A value of 1 implies a fully unrolled SHA-256 calculation spanning 64 round\n// modules and calculating a full SHA-256 hash every clock cycle. A value of\n// 2 implies a half-unrolled loop, with 32 round modules and calculating\n// a full hash in 2 clock cycles. And so forth.\n\nmodule sha256_transform #(\n\tparameter LOOP = 7'd64\t\t// For ltcminer\n) (\n\tinput clk,\n\tinput feedback,\n\tinput [5:0] cnt,\n\tinput [255:0] rx_state,\n\tinput [511:0] rx_input,\n\toutput reg [255:0] tx_hash\n);\n\n\t// Constants defined by the SHA-2 standard.\n\tlocalparam Ks = {\n\t\t32'h428a2f98, 32'h71374491, 32'hb5c0fbcf, 32'he9b5dba5,\n\t\t32'h3956c25b, 32'h59f111f1, 32'h923f82a4, 32'hab1c5ed5,\n\t\t32'hd807aa98, 32'h12835b01, 32'h243185be, 32'h550c7dc3,\n\t\t32'h72be5d74, 32'h80deb1fe, 32'h9bdc06a7, 32'hc19bf174,\n\t\t32'he49b69c1, 32'hefbe4786, 32'h0fc19dc6, 32'h240ca1cc,\n\t\t32'h2de92c6f, 32'h4a7484aa, 32'h5cb0a9dc, 32'h76f988da,\n\t\t32'h983e5152, 32'ha831c66d, 32'hb00327c8, 32'hbf597fc7,\n\t\t32'hc6e00bf3, 32'hd5a79147, 32'h06ca6351, 32'h14292967,\n\t\t32'h27b70a85, 32'h2e1b2138, 32'h4d2c6dfc, 32'h53380d13,\n\t\t32'h650a7354, 32'h766a0abb, 32'h81c2c92e, 32'h92722c85,\n\t\t32'ha2bfe8a1, 32'ha81a664b, 32'hc24b8b70, 32'hc76c51a3,\n\t\t32'hd192e819, 32'hd6990624, 32'hf40e3585, 32'h106aa070,\n\t\t32'h19a4c116, 32'h1e376c08, 32'h2748774c, 32'h34b0bcb5,\n\t\t32'h391c0cb3, 32'h4ed8aa4a, 32'h5b9cca4f, 32'h682e6ff3,\n\t\t32'h748f82ee, 32'h78a5636f, 32'h84c87814, 32'h8cc70208,\n\t\t32'h90befffa, 32'ha4506ceb, 32'hbef9a3f7, 32'hc67178f2};\n\n\n\tgenvar i;\n\n\tgenerate\n\n\t\tfor (i = 0; i < 64/LOOP; i = i + 1) begin : HASHERS\n\t\t\t// These are declared as registers in sha256_digester\n\t\t\twire [511:0] W;\t\t\t// reg tx_w\n\t\t\twire [255:0] state;\t\t// reg tx_state\n\n\t\t\tif(i == 0)\n\t\t\t\tsha256_digester U (\n\t\t\t\t\t.clk(clk),\n\t\t\t\t\t.k(Ks[32*(63-cnt) +: 32]),\n\t\t\t\t\t.rx_w(feedback ? W : rx_input),\n\t\t\t\t\t.rx_state(feedback ? state : rx_state),\n\t\t\t\t\t.tx_w(W),\n\t\t\t\t\t.tx_state(state)\n\t\t\t\t);\n\t\t\telse\n\t\t\t\tsha256_digester U (\n\t\t\t\t\t.clk(clk),\n\t\t\t\t\t.k(Ks[32*(63-LOOP*i-cnt) +: 32]),\n\t\t\t\t\t.rx_w(feedback ? W : HASHERS[i-1].W),\n\t\t\t\t\t.rx_state(feedback ? state : HASHERS[i-1].state),\n\t\t\t\t\t.tx_w(W),\n\t\t\t\t\t.tx_state(state)\n\t\t\t\t);\n\t\tend\n\n\tendgenerate\n\n\talways @ (posedge clk)\n\tbegin\n\t\tif (!feedback)\n\t\tbegin\n\t\t\ttx_hash[`IDX(0)] <= rx_state[`IDX(0)] + HASHERS[64/LOOP-6'd1].state[`IDX(0)];\n\t\t\ttx_hash[`IDX(1)] <= rx_state[`IDX(1)] + HASHERS[64/LOOP-6'd1].state[`IDX(1)];\n\t\t\ttx_hash[`IDX(2)] <= rx_state[`IDX(2)] + HASHERS[64/LOOP-6'd1].state[`IDX(2)];\n\t\t\ttx_hash[`IDX(3)] <= rx_state[`IDX(3)] + HASHERS[64/LOOP-6'd1].state[`IDX(3)];\n\t\t\ttx_hash[`IDX(4)] <= rx_state[`IDX(4)] + HASHERS[64/LOOP-6'd1].state[`IDX(4)];\n\t\t\ttx_hash[`IDX(5)] <= rx_state[`IDX(5)] + HASHERS[64/LOOP-6'd1].state[`IDX(5)];\n\t\t\ttx_hash[`IDX(6)] <= rx_state[`IDX(6)] + HASHERS[64/LOOP-6'd1].state[`IDX(6)];\n\t\t\ttx_hash[`IDX(7)] <= rx_state[`IDX(7)] + HASHERS[64/LOOP-6'd1].state[`IDX(7)];\n\t\tend\n\tend\n\n\nendmodule\n\n\nmodule sha256_digester (clk, k, rx_w, rx_state, tx_w, tx_state);\n\n\tinput clk;\n\tinput [31:0] k;\n\tinput [511:0] rx_w;\n\tinput [255:0] rx_state;\n\n\toutput reg [511:0] tx_w;\n\toutput reg [255:0] tx_state;\n\n\n\twire [31:0] e0_w, e1_w, ch_w, maj_w, s0_w, s1_w;\n\n\n\te0\te0_blk\t(rx_state[`IDX(0)], e0_w);\n\te1\te1_blk\t(rx_state[`IDX(4)], e1_w);\n\tch\tch_blk\t(rx_state[`IDX(4)], rx_state[`IDX(5)], rx_state[`IDX(6)], ch_w);\n\tmaj\tmaj_blk\t(rx_state[`IDX(0)], rx_state[`IDX(1)], rx_state[`IDX(2)], maj_w);\n\ts0\ts0_blk\t(rx_w[63:32], s0_w);\n\ts1\ts1_blk\t(rx_w[479:448], s1_w);\n\n\twire [31:0] t1 = rx_state[`IDX(7)] + e1_w + ch_w + rx_w[31:0] + k;\n\twire [31:0] t2 = e0_w + maj_w;\n\twire [31:0] new_w = s1_w + rx_w[319:288] + s0_w + rx_w[31:0];\n\t\n\n\talways @ (posedge clk)\n\tbegin\n\t\ttx_w[511:480] <= new_w;\n\t\ttx_w[479:0] <= rx_w[511:32];\n\n\t\ttx_state[`IDX(7)] <= rx_state[`IDX(6)];\n\t\ttx_state[`IDX(6)] <= rx_state[`IDX(5)];\n\t\ttx_state[`IDX(5)] <= rx_state[`IDX(4)];\n\t\ttx_state[`IDX(4)] <= rx_state[`IDX(3)] + t1;\n\t\ttx_state[`IDX(3)] <= rx_state[`IDX(2)];\n\t\ttx_state[`IDX(2)] <= rx_state[`IDX(1)];\n\t\ttx_state[`IDX(1)] <= rx_state[`IDX(0)];\n\t\ttx_state[`IDX(0)] <= t1 + t2;\n\tend\n\nendmodule\n"
  },
  {
    "path": "experimental/CM1/uart.v",
    "content": "`timescale 1ns / 1ps\n//////////////////////////////////////////////////////////////////////////////////\n// UART Module\n// Paul Mumby 2012\n//////////////////////////////////////////////////////////////////////////////////\nmodule uart(\n\t\tclk,\n\t\trx_pin,\n\t\ttx_pin,\n\t\trx_byte,\n\t\ttx_byte,\n\t\trx_data_ready,\n\t\ttx_start,\n\t\trx_busy,\n\t\ttx_busy,\n\t\trx_error\n\t);\n\n\t//Parameters:\n\t//================================================\n\tparameter CLOCK = 25000000; \t//Overridden by parent \n\tparameter BAUD = 9600;\t\t\t//Overridden by parent\n\tparameter SAMPLE_POINT = 8;\t//Overridden by parent\n\t\n\t//IO Definitions:\n\t//================================================\n\tinput clk;\n\tinput rx_pin;\n\toutput tx_pin;\n\toutput [7:0] rx_byte;\n\tinput [7:0] tx_byte;\n\toutput rx_data_ready;\n\tinput tx_start;\n\toutput rx_busy;\n\toutput tx_busy;\n\toutput rx_error;\n\t\n\t//Register/Wire Definitions:\n\t//================================================\n\t\n\t//BUFG Instatiation:\n\t//================================================\n\t\n\t//Module Instantiation:\n\t//================================================\n\tuart_tx #(\n\t\t.CLOCK(CLOCK),\n\t\t.BAUD(BAUD)\n\t) TXCORE (\n\t\t.clk(clk),\n\t\t.tx(tx_pin),\n\t\t.tx_byte(tx_byte),\n\t\t.start(tx_start),\n\t\t.busy(tx_busy)\n\t);\n\n\tuart_rx #(\n\t\t.CLOCK(CLOCK),\n\t\t.BAUD(BAUD),\n\t\t.SAMPLE_POINT(SAMPLE_POINT)\n\t) RXCORE (\n\t\t.clk(clk),\n\t\t.rx(rx_pin),\n\t\t.rx_byte(rx_byte),\n\t\t.data_ready(rx_data_ready),\n\t\t.busy(rx_busy),\n\t\t.error(rx_error)\n\t);\n\t\n\t//Assignments:\n\t//================================================\n\t\n\t//Toplevel Logic:\n\t//================================================\n\nendmodule\n"
  },
  {
    "path": "experimental/CM1/uart_baudgenerator.v",
    "content": "`timescale 1ns / 1ps\n//////////////////////////////////////////////////////////////////////////////////\n// Baud Generator Core\n// Paul Mumby 2012\n// Originally derived from code examples at:\n// http://www.fpga4fun.com\n//////////////////////////////////////////////////////////////////////////////////\n\nmodule uart_baudgenerator(\n\t\tclk,\n\t\tbaudtick\n\t);\n\n\t//Parameters:\n\t//================================================\n\tparameter CLOCK = 25000000; // 25MHz\n\tparameter BAUD = 9600;\n\tparameter ACCWIDTH = 16;\n\tparameter ROUNDBITS = 5;\n\tparameter INC = ((BAUD<<(ACCWIDTH-(ROUNDBITS-1)))+(CLOCK>>ROUNDBITS))/(CLOCK>>(ROUNDBITS-1));\n\n\t//IO Definitions:\n\t//================================================\n\tinput clk;\n\toutput baudtick;\n\t\n\t//Register/Wire Definitions:\n\t//================================================\n\treg [ACCWIDTH:0] accumulator = 0;\n\t\n\t//BUFG Instatiation:\n\t//================================================\n\t\n\t//Module Instantiation:\n\t//================================================\n\t\n\t//Assignments:\n\t//================================================\n\tassign baudtick = accumulator[ACCWIDTH];\n\t\n\t//Toplevel Logic:\n\t//================================================\n\talways @(posedge clk)\n\t\taccumulator <= accumulator[ACCWIDTH-1:0] + INC;\n\nendmodule\n\n"
  },
  {
    "path": "experimental/CM1/uart_rx.v",
    "content": "`timescale 1ns / 1ps\n//////////////////////////////////////////////////////////////////////////////////\n// UART RX Module\n// Paul Mumby 2012\n// Originally derived from code examples at:\n// http://www.fpga4fun.com\n//////////////////////////////////////////////////////////////////////////////////\nmodule uart_rx(\n\t\tclk,\t\t\t//Communications Clock\n\t\trx,\t\t\t//Tx IO Pin\n\t\trx_byte,\t\t//Byte to Transmit\n\t\tdata_ready,\t\t//Start Transmitting Byte\n\t\tbusy,\t\t\t//Tx Busy Flag\n\t\terror\n\t);\n\n\t//Parameters:\n\t//================================================\n\tparameter CLOCK = 25000000; \t//Overridden by parent UART core\n\tparameter BAUD = 9600;\t\t\t//Overridden by parent UART core\n\tparameter SAMPLE_POINT = 8;\t//Overridden by parent\n\n\t//IO Definitions:\n\t//================================================\n\tinput clk;\n\twire baudtick;\n\tinput rx;\n\toutput reg [7:0] rx_byte;\n\toutput reg data_ready;\n\toutput busy;\n\toutput reg error;\n\t\n\t//Register/Wire Definitions:\n\t//================================================\n\treg [1:0] rx_sync;\n\treg [1:0] rx_counter;\n\treg rx_bit;\n\treg [3:0] state;\n\treg [3:0] bit_spacing;\n\treg [4:0] data_gap;\n\treg rx_buf1, rx_buf2;\n\twire next_bit;\n\twire rx_n;\n\t\n\t//BUFG Instatiation:\n\t//================================================\n\t\n\t//Module Instantiation:\n\t//================================================\n\tuart_baudgenerator #(\n\t\t.CLOCK(CLOCK),\n\t\t.BAUD(BAUD*8),\t//Oversampled\n\t\t.ROUNDBITS(8)\t//Higher frequency requires more rounding\n\t) BAUDGEN (\n\t\t.clk(clk),\n\t\t.baudtick(baudtick)\n\t);\n\n\t//Assignments:\n\t//================================================\n\t\n\t//Inverted rx for stability:\n\tassign rx_n = ~rx_buf2;\n\t//Note: value below for bit_spacing check, defines where data sampling occurs\n\tassign next_bit = (bit_spacing==SAMPLE_POINT);\n\t//Gap Detection:\n\tassign busy = ~data_gap[4];\n\t\n\t//Toplevel Logic:\n\t//================================================\n\t\n\t//Double Buffering\n\talways @(posedge clk)\n\t\tbegin\n\t\t\trx_buf1 <= rx;\n\t\t\trx_buf2 <= rx_buf1;\n\t\tend\n\t\n\t//Oversampling & Sync of RX Input to clock\n\talways @(posedge clk)\n\t\tif(baudtick)\n\t\t\trx_sync <= {rx_sync[0], rx_n};\n\t\n\t//RX Line Noise Filter\n\talways @(posedge clk)\n\t\tif(baudtick)\n\t\t\tbegin\n\t\t\t\tif(rx_sync[1] && rx_counter!=2'b11)\n\t\t\t\t\trx_counter <= rx_counter + 2'h1;\n\t\t\t\tif(~rx_sync[1] && rx_counter!=2'b00)\n\t\t\t\t\trx_counter <= rx_counter - 2'h1;\n\t\t\t\tif(rx_counter==2'b00)\n\t\t\t\t\trx_bit <= 1'b0;\n\t\t\t\telse if(rx_counter==2'b11)\n\t\t\t\t\trx_bit <= 1'b1;\n\t\t\tend\n\t\n\t//RX State Machine\n\talways @(posedge clk)\n\t\tif(baudtick)\n\t\t\tcase(state)\n\t\t\t\t4'b0000: if(rx_bit) state <= 4'b1000; // start bit found?\n\t\t\t\t4'b1000: if(next_bit) state <= 4'b1001; // bit 0\n\t\t\t\t4'b1001: if(next_bit) state <= 4'b1010; // bit 1\n\t\t\t\t4'b1010: if(next_bit) state <= 4'b1011; // bit 2\n\t\t\t\t4'b1011: if(next_bit) state <= 4'b1100; // bit 3\n\t\t\t\t4'b1100: if(next_bit) state <= 4'b1101; // bit 4\n\t\t\t\t4'b1101: if(next_bit) state <= 4'b1110; // bit 5\n\t\t\t\t4'b1110: if(next_bit) state <= 4'b1111; // bit 6\n\t\t\t\t4'b1111: if(next_bit) state <= 4'b0001; // bit 7\n\t\t\t\t4'b0001: if(next_bit) state <= 4'b0000; // stop bit\n\t\t\t\tdefault: state <= 4'b0000;\n\t\t\tendcase\n\t\n\t//Bit Spacing Detection\n\talways @(posedge clk)\n\t\tif(state==0)\n\t\t\tbit_spacing <= 4'b0000;\n\t\telse if(baudtick)\n\t\t\tbit_spacing <= {bit_spacing[2:0] + 4'b0001} | {bit_spacing[3], 3'b000};\n\n\t//Shift Register\n\talways @(posedge clk)\n\t\tif(baudtick && next_bit && state[3]) \n\t\t\trx_byte <= {~rx_bit, rx_byte[7:1]};\n\t\n\t//Data Ready & Error Detection\n\talways @(posedge clk)\n\t\tbegin\n\t\t\tdata_ready <= (baudtick && next_bit && state==4'b0001 && ~rx_bit);  // ready only if the stop bit is received\n\t\t\terror <= (baudtick && next_bit && state==4'b0001 && rx_bit);  // error if no stop bit received\n\t\tend\n\t\n\t//Idle Detection\n\talways @(posedge clk)\n\t\tif(state!=0)\n\t\t\tdata_gap <= 5'h00;\n\t\telse if(baudtick & ~data_gap[4])\n\t\t\tdata_gap <= data_gap + 5'h01;\n\t\nendmodule\n"
  },
  {
    "path": "experimental/CM1/uart_tx.v",
    "content": "`timescale 1ns / 1ps\n//////////////////////////////////////////////////////////////////////////////////\n// UART TX Module\n// Paul Mumby 2012\n// Originally derived from code examples at:\n// http://www.fpga4fun.com\n//////////////////////////////////////////////////////////////////////////////////\nmodule uart_tx(\n\t\tclk,\t\t\t//Communications Clock\n\t\ttx,\t\t\t//Tx IO Pin\n\t\ttx_byte,\t\t//Byte to Transmit\n\t\tstart,\t\t//Start Transmitting Byte\n\t\tbusy\t\t\t//Tx Busy Flag\n\t);\n\n\t//Parameters:\n\t//================================================\n\tparameter CLOCK = 25000000; \t//Overridden by parent UART core\n\tparameter BAUD = 9600;\t\t\t//Overridden by parent UART core\n\n\t//IO Definitions:\n\t//================================================\n\tinput clk;\n\twire baudtick;\n\toutput reg tx;\n\tinput [7:0] tx_byte;\n\tinput start;\n\toutput busy;\n\t\n\t//Register/Wire Definitions:\n\t//================================================\n\treg [3:0] state = 0;\n\treg [7:0] byte_buf;\n\treg muxflag;\n\twire ready;\n\t\t\n\t//BUFG Instatiation:\n\t//================================================\n\t\n\t//Module Instantiation:\n\t//================================================\n\tuart_baudgenerator #(\n\t\t.CLOCK(CLOCK),\n\t\t.BAUD(BAUD),\n\t\t.ROUNDBITS(5)\n\t) BAUDGEN (\n\t\t.clk(clk),\n\t\t.baudtick(baudtick)\n\t);\n\n\t//Assignments:\n\t//================================================\n\tassign ready = (state==0);\n\tassign busy = ~ready;\n\t\n\t//Toplevel Logic:\n\t//================================================\n\t\n\t//Buffer Logic:\n\talways @(posedge clk)\n\t\tif(ready & start)\n\t\t\tbyte_buf <= tx_byte;\n\t\n\t//Tx State Machine\n\talways @(posedge clk)\n\t\tcase(state)\n\t\t\t4'b0000: if(start) state <= 4'b0001;\n\t\t\t4'b0001: if(baudtick) state <= 4'b0100;\n\t\t\t4'b0100: if(baudtick) state <= 4'b1000;  // start\n\t\t\t4'b1000: if(baudtick) state <= 4'b1001;  // bit 0\n\t\t\t4'b1001: if(baudtick) state <= 4'b1010;  // bit 1\n\t\t\t4'b1010: if(baudtick) state <= 4'b1011;  // bit 2\n\t\t\t4'b1011: if(baudtick) state <= 4'b1100;  // bit 3\n\t\t\t4'b1100: if(baudtick) state <= 4'b1101;  // bit 4\n\t\t\t4'b1101: if(baudtick) state <= 4'b1110;  // bit 5\n\t\t\t4'b1110: if(baudtick) state <= 4'b1111;  // bit 6\n\t\t\t4'b1111: if(baudtick) state <= 4'b0010;  // bit 7\n\t\t\t4'b0010: if(baudtick) state <= 4'b0011;  // stop1\n\t\t\t4'b0011: if(baudtick) state <= 4'b0000;  // stop2\n\t\t\tdefault: if(baudtick) state <= 4'b0000;\t\t\n\t\tendcase\n\n\t//Mux Logic\n\talways @(*)\n\t\tcase(state[2:0])\n\t\t\t3'd0: muxflag <= byte_buf[0];\n\t\t\t3'd1: muxflag <= byte_buf[1];\n\t\t\t3'd2: muxflag <= byte_buf[2];\n\t\t\t3'd3: muxflag <= byte_buf[3];\n\t\t\t3'd4: muxflag <= byte_buf[4];\n\t\t\t3'd5: muxflag <= byte_buf[5];\n\t\t\t3'd6: muxflag <= byte_buf[6];\n\t\t\t3'd7: muxflag <= byte_buf[7];\n\t\tendcase\n\n\t//TX IO Drive Logic\n\talways @(posedge clk)\n\t\ttx <= (state<4) | (state[3] & muxflag);\n\nendmodule\n"
  },
  {
    "path": "experimental/CM1/xilinx_ram.v",
    "content": "// xilinx_ram.v - inferring the ram seems to work fine\n\nmodule ram # ( parameter ADDRBITS=10 ) (\n\traddr,\n\twaddr,\n\tclock,\n\tdata,\n\twren,\n\tq);\n\n\tinput\t[ADDRBITS-1:0]  raddr;\n\tinput\t[ADDRBITS-1:0]  waddr;\n\tinput\t  clock;\n\tinput\t[255:0]  data;\n\tinput\t  wren;\n\toutput\t[255:0]  q;\n\n\t//synthesis attribute ram_style of store is block\n\treg [255:0] store [(2 << (ADDRBITS-1))-1:0];\n\treg[ADDRBITS-1:0] raddr_reg;\n\t\n\talways @ (posedge clock)\n\tbegin\n\t\traddr_reg <= raddr;\n\t\tif (wren)\n\t\t\tstore[waddr] <= data;\n\tend\n\t\n\tassign q = store[raddr_reg];\n\t\t\t\nendmodule"
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/README.txt",
    "content": "This is untested, but simulates OK, so it ought to work after a fashion\n(at least for the single core variant).\n\nI'm not entirely happy with the loadnonce behaviour (it really ought to\nstrobe on loading new data so as to initiate a reset), but this is a bit\ntricky as the virtual_wire interface seems to be non-deterministic.\n\nI've left the ICARUS macro defined in pbkdfengine.v as this matches the\nworking lancelot/ztex/CM1 ports, and since I can't test it live I'm leaving\nit alone but this does disable the load nonce test feature. It really ought\nto be undefined for altera, perhaps also initiating a reset on the comparison\n(nonce_previous_load != data3[127:96])."
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/altera_pll.v",
    "content": "module main_pll # (parameter SPEED_MHZ = 25) (inclk0, c0);\n\n\tinput\t  inclk0;\n\toutput\t  c0;\n\n\twire [4:0] sub_wire0;\n\twire [0:0] sub_wire4 = 1'h0;\n\twire [0:0] sub_wire1 = sub_wire0[0:0];\n\twire  c0 = sub_wire1;\n\twire  sub_wire2 = inclk0;\n\twire [1:0] sub_wire3 = {sub_wire4, sub_wire2};\n\n\taltpll\taltpll_component (\n\t\t\t\t.inclk (sub_wire3),\n\t\t\t\t.clk (sub_wire0),\n\t\t\t\t.activeclock (),\n\t\t\t\t.areset (1'b0),\n\t\t\t\t.clkbad (),\n\t\t\t\t.clkena ({6{1'b1}}),\n\t\t\t\t.clkloss (),\n\t\t\t\t.clkswitch (1'b0),\n\t\t\t\t.configupdate (1'b0),\n\t\t\t\t.enable0 (),\n\t\t\t\t.enable1 (),\n\t\t\t\t.extclk (),\n\t\t\t\t.extclkena ({4{1'b1}}),\n\t\t\t\t.fbin (1'b1),\n\t\t\t\t.fbmimicbidir (),\n\t\t\t\t.fbout (),\n\t\t\t\t// synopsys translate_off\n\t\t\t\t.fref (),\n\t\t\t\t.icdrclk (),\n\t\t\t\t// synopsys translate_on\n\t\t\t\t.locked (),\n\t\t\t\t.pfdena (1'b1),\n\t\t\t\t.phasecounterselect ({4{1'b1}}),\n\t\t\t\t.phasedone (),\n\t\t\t\t.phasestep (1'b1),\n\t\t\t\t.phaseupdown (1'b1),\n\t\t\t\t.pllena (1'b1),\n\t\t\t\t.scanaclr (1'b0),\n\t\t\t\t.scanclk (1'b0),\n\t\t\t\t.scanclkena (1'b1),\n\t\t\t\t.scandata (1'b0),\n\t\t\t\t.scandataout (),\n\t\t\t\t.scandone (),\n\t\t\t\t.scanread (1'b0),\n\t\t\t\t.scanwrite (1'b0),\n\t\t\t\t.sclkout0 (),\n\t\t\t\t.sclkout1 (),\n\t\t\t\t.vcooverrange (),\n\t\t\t\t.vcounderrange ());\n\tdefparam\n\t\taltpll_component.bandwidth_type = \"AUTO\",\n\t\taltpll_component.clk0_divide_by = 50,\n\t\taltpll_component.clk0_duty_cycle = 50,\n\t\taltpll_component.clk0_multiply_by = SPEED_MHZ,\n\t\taltpll_component.clk0_phase_shift = \"0\",\n\t\taltpll_component.compensate_clock = \"CLK0\",\n\t\taltpll_component.inclk0_input_frequency = 20000,\n\t\taltpll_component.intended_device_family = \"Cyclone III\",\n\t\taltpll_component.lpm_hint = \"CBX_MODULE_PREFIX=main_pll\",\n\t\taltpll_component.lpm_type = \"altpll\",\n\t\taltpll_component.operation_mode = \"NORMAL\",\n\t\taltpll_component.pll_type = \"AUTO\",\n\t\taltpll_component.port_activeclock = \"PORT_UNUSED\",\n\t\taltpll_component.port_areset = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkbad0 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkbad1 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkloss = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkswitch = \"PORT_UNUSED\",\n\t\taltpll_component.port_configupdate = \"PORT_UNUSED\",\n\t\taltpll_component.port_fbin = \"PORT_UNUSED\",\n\t\taltpll_component.port_inclk0 = \"PORT_USED\",\n\t\taltpll_component.port_inclk1 = \"PORT_UNUSED\",\n\t\taltpll_component.port_locked = \"PORT_UNUSED\",\n\t\taltpll_component.port_pfdena = \"PORT_UNUSED\",\n\t\taltpll_component.port_phasecounterselect = \"PORT_UNUSED\",\n\t\taltpll_component.port_phasedone = \"PORT_UNUSED\",\n\t\taltpll_component.port_phasestep = \"PORT_UNUSED\",\n\t\taltpll_component.port_phaseupdown = \"PORT_UNUSED\",\n\t\taltpll_component.port_pllena = \"PORT_UNUSED\",\n\t\taltpll_component.port_scanaclr = \"PORT_UNUSED\",\n\t\taltpll_component.port_scanclk = \"PORT_UNUSED\",\n\t\taltpll_component.port_scanclkena = \"PORT_UNUSED\",\n\t\taltpll_component.port_scandata = \"PORT_UNUSED\",\n\t\taltpll_component.port_scandataout = \"PORT_UNUSED\",\n\t\taltpll_component.port_scandone = \"PORT_UNUSED\",\n\t\taltpll_component.port_scanread = \"PORT_UNUSED\",\n\t\taltpll_component.port_scanwrite = \"PORT_UNUSED\",\n\t\taltpll_component.port_clk0 = \"PORT_USED\",\n\t\taltpll_component.port_clk1 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clk2 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clk3 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clk4 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clk5 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkena0 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkena1 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkena2 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkena3 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkena4 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkena5 = \"PORT_UNUSED\",\n\t\taltpll_component.port_extclk0 = \"PORT_UNUSED\",\n\t\taltpll_component.port_extclk1 = \"PORT_UNUSED\",\n\t\taltpll_component.port_extclk2 = \"PORT_UNUSED\",\n\t\taltpll_component.port_extclk3 = \"PORT_UNUSED\",\n\t\taltpll_component.width_clock = 5;\n\n\nendmodule\n\n"
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/altera_virtual_wire.v",
    "content": "/*\n*\n* Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n*\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n\nmodule virtual_wire (probe, source);\n\t\n\tparameter WIDTH = 1;\n\tparameter PROBE_WIDTH = 1;\n\tparameter INITIAL_VALUE = \" 0\";\n\tparameter INSTANCE_ID = \"NONE\";\n\n\tinput\t[0:PROBE_WIDTH-1]  probe;\n\toutput\t[0:WIDTH-1]  source;\n\n`ifdef SIM\n\tassign source = 0;\n`else\n\taltsource_probe\taltsource_probe_component (\n\t\t\t\t.probe (probe),\n\t\t\t\t.source (source)\n\t\t\t\t// synopsys translate_off\n\t\t\t\t,\n\t\t\t\t.clrn (),\n\t\t\t\t.ena (),\n\t\t\t\t.ir_in (),\n\t\t\t\t.ir_out (),\n\t\t\t\t.jtag_state_cdr (),\n\t\t\t\t.jtag_state_cir (),\n\t\t\t\t.jtag_state_e1dr (),\n\t\t\t\t.jtag_state_sdr (),\n\t\t\t\t.jtag_state_tlr (),\n\t\t\t\t.jtag_state_udr (),\n\t\t\t\t.jtag_state_uir (),\n\t\t\t\t.raw_tck (),\n\t\t\t\t.source_clk (),\n\t\t\t\t.source_ena (),\n\t\t\t\t.tdi (),\n\t\t\t\t.tdo (),\n\t\t\t\t.usr1 ()\n\t\t\t\t// synopsys translate_on\n\t\t\t\t);\n\tdefparam\n\t\taltsource_probe_component.enable_metastability = \"NO\",\n\t\taltsource_probe_component.instance_id = INSTANCE_ID,\n\t\taltsource_probe_component.probe_width = PROBE_WIDTH,\n\t\taltsource_probe_component.sld_auto_instance_index = \"YES\",\n\t\taltsource_probe_component.sld_instance_index = 0,\n\t\taltsource_probe_component.source_initial_value = INITIAL_VALUE,\n\t\taltsource_probe_component.source_width = WIDTH;\n`endif\n\nendmodule\n\n"
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/ltcminer.qpf",
    "content": "# -------------------------------------------------------------------------- #\n#\n# Copyright (C) 1991-2010 Altera Corporation\n# Your use of Altera Corporation's design tools, logic functions \n# and other software and tools, and its AMPP partner logic \n# functions, and any output files from any of the foregoing \n# (including device programming or simulation files), and any \n# associated documentation or information are expressly subject \n# to the terms and conditions of the Altera Program License \n# Subscription Agreement, Altera MegaCore Function License \n# Agreement, or other applicable license agreement, including, \n# without limitation, that your use is for the sole purpose of \n# programming logic devices manufactured by Altera and sold by \n# Altera or its authorized distributors.  Please refer to the \n# applicable agreement for further details.\n#\n# -------------------------------------------------------------------------- #\n#\n# Quartus II\n# Version 10.1 Build 153 11/29/2010 SJ Web Edition\n# Date created = 19:35:13  July 19, 2013\n#\n# -------------------------------------------------------------------------- #\n\nQUARTUS_VERSION = \"10.1\"\nDATE = \"19:35:13  July 19, 2013\"\n\n# Revisions\n\nPROJECT_REVISION = \"ltcminer\"\nPROJECT_REVISION = \"ltcaminer\"\n"
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/ltcminer.qsf",
    "content": "# -------------------------------------------------------------------------- #\n#\n# Copyright (C) 1991-2010 Altera Corporation\n# Your use of Altera Corporation's design tools, logic functions\n# and other software and tools, and its AMPP partner logic\n# functions, and any output files from any of the foregoing\n# (including device programming or simulation files), and any\n# associated documentation or information are expressly subject\n# to the terms and conditions of the Altera Program License\n# Subscription Agreement, Altera MegaCore Function License\n# Agreement, or other applicable license agreement, including,\n# without limitation, that your use is for the sole purpose of\n# programming logic devices manufactured by Altera and sold by\n# Altera or its authorized distributors.  Please refer to the\n# applicable agreement for further details.\n#\n# -------------------------------------------------------------------------- #\n#\n# Quartus II\n# Version 10.0 Build 262 08/18/2010 Service Pack 1 SJ Web Edition\n# Date created = 05:05:52  March 02, 2011\n#\n# -------------------------------------------------------------------------- #\n#\n# Notes:\n#\n# 1) The default values for assignments are stored in the file:\n#    If this file doesn't exist, see file:\n#\t\tassignment_defaults.qdf\n#\n# 2) Altera recommends that you do not modify this file. This\n#    file is updated automatically by the Quartus II software\n#    and any changes you make may be lost or overwritten.\n#\n# -------------------------------------------------------------------------- #\n\n\nset_global_assignment -name FAMILY \"Cyclone IV E\"\nset_global_assignment -name DEVICE EP4CE115F29C7\nset_global_assignment -name TOP_LEVEL_ENTITY ltcminer\nset_global_assignment -name ORIGINAL_QUARTUS_VERSION \"10.0 SP1\"\nset_global_assignment -name PROJECT_CREATION_TIME_DATE \"17:52:09  MAY 05, 2011\"\nset_global_assignment -name LAST_QUARTUS_VERSION 10.1\nset_global_assignment -name MIN_CORE_JUNCTION_TEMP 0\nset_global_assignment -name MAX_CORE_JUNCTION_TEMP 85\nset_global_assignment -name DEVICE_FILTER_SPEED_GRADE 7\nset_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1\nset_global_assignment -name STRATIX_DEVICE_IO_STANDARD \"2.5 V\"\nset_location_assignment PIN_Y2 -to osc_clk\nset_instance_assignment -name IO_STANDARD \"3.3-V LVTTL\" -to osc_clk\nset_global_assignment -name ENABLE_SIGNALTAP OFF\nset_global_assignment -name POWER_PRESET_COOLING_SOLUTION \"23 MM HEAT SINK WITH 200 LFPM AIRFLOW\"\nset_global_assignment -name POWER_BOARD_THERMAL_MODEL \"NONE (CONSERVATIVE)\"\nset_global_assignment -name ALLOW_ANY_RAM_SIZE_FOR_RECOGNITION ON\nset_global_assignment -name ALLOW_ANY_SHIFT_REGISTER_SIZE_FOR_RECOGNITION ON\nset_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top\nset_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top\nset_global_assignment -name PARTITION_COLOR 16764057 -section_id Top\nset_global_assignment -name LL_ROOT_REGION ON -section_id \"Root Region\"\nset_global_assignment -name LL_MEMBER_STATE LOCKED -section_id \"Root Region\"\nset_global_assignment -name PROJECT_OUTPUT_DIRECTORY quartus_output\nset_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON\nset_global_assignment -name ALLOW_ANY_ROM_SIZE_FOR_RECOGNITION ON\nset_global_assignment -name EDA_SIMULATION_TOOL \"<None>\"\nset_global_assignment -name EDA_MAP_ILLEGAL_CHARACTERS OFF -section_id eda_simulation\nset_global_assignment -name EDA_TIME_SCALE \"1 ps\" -section_id eda_simulation\nset_global_assignment -name EDA_OUTPUT_DATA_FORMAT NONE -section_id eda_simulation\nset_global_assignment -name EDA_ENABLE_GLITCH_FILTERING OFF -section_id eda_simulation\nset_global_assignment -name EDA_WRITE_NODES_FOR_POWER_ESTIMATION OFF -section_id eda_simulation\nset_global_assignment -name EDA_TEST_BENCH_DESIGN_INSTANCE_NAME moogerfoogin -section_id eda_simulation\nset_global_assignment -name POWER_USE_PVA OFF\nset_global_assignment -name POWER_DEFAULT_TOGGLE_RATE 65%\nset_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF\nset_global_assignment -name VERILOG_FILE \"ltcminer.v\"\nset_global_assignment -name VERILOG_FILE \"pbkdfengine.v\"\nset_global_assignment -name VERILOG_FILE \"salsaengine.v\"\nset_global_assignment -name VERILOG_FILE \"sim_ram.v\"\nset_global_assignment -name VERILOG_FILE \"salsa_slowsixteen.v\"\nset_global_assignment -name VERILOG_FILE \"sha256_transform.v\"\nset_global_assignment -name VERILOG_FILE \"sha-256-functions.v\"\nset_global_assignment -name VERILOG_FILE \"altera_pll.v\"\nset_global_assignment -name VERILOG_FILE \"altera_virtual_wire.v\"\nset_global_assignment -name VERILOG_MACRO \"NOLEDS=1\"\nset_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top"
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/ltcminer.sdc",
    "content": "##\n#\n# Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n#\n#\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n# \n##\n\ncreate_clock -period 20.000 -name osc_clk osc_clk\n\nderive_pll_clocks\nderive_clock_uncertainty\n\n"
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/ltcminer.v",
    "content": "/* ltcminer.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`ifdef NOLEDS\n\tmodule ltcminer (osc_clk);\t\t// Version without LEDs for DE2-115\n`else\n\tmodule ltcminer (osc_clk, LEDS_out);\n`endif\n\t\n`ifdef SPEED_MHZ\n\tparameter SPEED_MHZ = `SPEED_MHZ;\n`else\n\tparameter SPEED_MHZ = 25;\n`endif\n\n// LOCAL_MINERS determines the number of cores (the terminology is consistent with the LX150 port)\n`ifdef LOCAL_MINERS\n\tparameter LOCAL_MINERS = `LOCAL_MINERS;\n`else\n\tparameter LOCAL_MINERS = 1;\n`endif\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n`ifdef ADDRBITS\n\tparameter ADDRBITS = `ADDRBITS;\t\t\t\t\t// Override for simulation\n`else\n\tparameter ADDRBITS = 12 - clog2(LOCAL_MINERS);\t// Automatically selects largest RAM that will fit into 4MBit\n`endif\n\n\tlocalparam SBITS = 8;\t\t// Shift data path width\n\n\tinput osc_clk;\n`ifndef NOLEDS\n\toutput reg [7:0]LEDS_out;\t\t\t// Optional progress indicator\n`endif\n\n\twire hash_clk;\n\t`ifndef SIM\n\t\tmain_pll #(.SPEED_MHZ(SPEED_MHZ)) pll_blk (osc_clk, hash_clk);\n\t`else\n\t \tassign hash_clk = osc_clk;\n\t`endif\n\n// Virtual wire is now done here rather than in hashcore so as to support MULTICORE\t\n\n`ifndef SIM\n\t// 80 byte block header (NB this implimetation does not use midstate)\n\treg [255:0] data1 = 256'd0;\n\treg [255:0] data2 = 256'd0;\n\treg [127:0] data3 = 128'd0;\n\t// final_hash=553a4b69b43913a61b42013ce210f713eaa7332e48cda1bdf3b93b10161d0876 (NOT a match)\n`else\n\t// Test data (MATCH nonce 0000318f)\n\treg [255:0] data1 = 256'h18e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\treg [255:0] data2 = 256'hc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af755756;\n\treg [127:0] data3 = 128'h0000318f7e71441b141fe951b2b0c7df;\t// NB 0000318f is loaded into nonce\n\t// final_hash=b303000066bd9f068aa115339cfd01cd94121ef65b2ff4d7d3796b738a174f7b (MATCH at target=000007ff/diff=32)\n`endif\n\t\n\treg [31:0] target = 31'h000007ff;\t// Default to diff=32 for sane startup, this is overwritten by virtual_wire\n\n\twire [31:0]golden_nonce_out;\n\twire [31:0] nonce_out;\n\twire loadnonce = 1'b0;\t\t\t\t// Ought to strobe this when data changes, but this is not trivial as\n\t\t\t\t\t\t\t\t\t\t// the virtual_wire channels do not seem to update deterministically\n\twire [LOCAL_MINERS*32-1:0] golden_nonce_i;\n\twire [LOCAL_MINERS-1:0] golden_nonce_match;\n\n\twire pbkdf_clk = hash_clk;\t\t\t// Use same clock for now\n\n\tgenerate\n\t\tgenvar i;\n\t\tfor (i = 0; i < LOCAL_MINERS; i = i + 1)\n\t\tbegin: miners\n\t\t\twire [31:0] nonce_out_i;\n\t\t\twire [3:0] nonce_core = i;\n\t\t\twire gn_match;\n\t\t\twire salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift;\n\t\t\twire [SBITS-1:0] salsa_din;\n\t\t\twire [SBITS-1:0] salsa_dout;\n\t\t\twire [3:0] dummy;\t// So we can ignore top 4 bits of slave_debug_sr\n\n\t\t\t// Currently one pbkdfengine per salsaengine - TODO share the pbkdfengine for several salsaengines\n\t\t\tpbkdfengine #(.SBITS(SBITS)) P\n\t\t\t\t(.hash_clk(hash_clk), .pbkdf_clk(pbkdf_clk), .data1(data1), .data2(data2), .data3(data3), .target(target),\n\t\t\t\t.nonce_msb({nonce_core}), .nonce_out(nonce_out_i), .golden_nonce_out(golden_nonce_i[(i+1)*32-1:i*32]),\n\t\t\t\t.golden_nonce_match(golden_nonce_match[i]), .loadnonce(loadnonce),\n\t\t\t\t.salsa_din(salsa_din), .salsa_dout(salsa_dout), .salsa_busy(salsa_busy), .salsa_result(salsa_result),\n\t\t\t\t.salsa_reset(salsa_reset), .salsa_start(salsa_start), .salsa_shift(salsa_shift));\n\n\t\t\tsalsaengine #(.ADDRBITS(ADDRBITS), .SBITS(SBITS)) S\n\t\t\t\t(.hash_clk(hash_clk), .reset(salsa_reset), .din(salsa_din), .dout(salsa_dout),\n\t\t\t\t.shift(salsa_shift), .start(salsa_start), .busy(salsa_busy), .result(salsa_result) );\n\t\t\t\t\t\n\t\t\t\n\t\t\tif (i==0)\n\t\t\t\tassign nonce_out = nonce_out_i;\t// NB mining script will under-report hash rate by factor of LOCAL_MINERS\n\t\t\t\t\t\t\t\t\t\t\t\t// TODO correctabe by a simple shift here of log2(LOCAL-MINERS)\n\n\t\tend // for\n\tendgenerate\n\t\n\t// Simple queue as virtual_wire just reports current value of golden_nonce\n\t\n\t// What I want here is a parameterised, one-hot (priority) selected multiplexor, but since\n\t// my verilog is not very good, I'll just reuse the hub_core code instead\n\t\n\treg [LOCAL_MINERS-1:0]new_nonces_flag = 0;\n   \n\treg [clog2(LOCAL_MINERS)+1:0] port_counter = 0;\n\treg [LOCAL_MINERS*32-1:0] nonces_shifted = 0;\n\tassign golden_nonce_out = nonces_shifted[31:0];\n\n\t// Mark nonces to be cleared during next clock cycle\n\treg [LOCAL_MINERS-1:0] clear_nonces = 0;\n\n\talways @(posedge pbkdf_clk)\n\tbegin\n\t\t// Raise flags when new nonces appear; lower those that have been sent\n\t\tnew_nonces_flag <= (new_nonces_flag & ~clear_nonces) | golden_nonce_match;\n\n\t\tif (port_counter == LOCAL_MINERS-1)\n\t\t\tport_counter <= 0;\n\t\telse\n\t\t\tport_counter <= port_counter + 1'd1;\n\t\t\n\t\t// kramble - the optimiser removes all but the low 32 bits of nonces_shifted since\n\t\t// the following code implements a multiplexor on nonces input, NOT an actual shifter.\n\t\tif (new_nonces_flag[port_counter])\n\t\tbegin\n\t\t\tnonces_shifted <= golden_nonce_i >> port_counter*32;\n\t\t\tclear_nonces[port_counter] <= 1;\n\t\tend\n\t\telse \n\t\tbegin\n\t\t\tclear_nonces <= 0;\n\t\tend\n\tend\n\t\n\t`ifndef SIM\n\n\t//// Virtual Wire Control\n\twire [255:0] data1_vw;\n\twire [255:0] data2_vw;\n\twire [127:0] data3_vw;\t\t// 96 bits actually used, the extra 32 are the nonce, normally all zeros but for\n\t\t\t\t\t\t\t\t// testing we can supply a nonce which will be loaded. Some pools set a non-zero nonce\n\t\t\t\t\t\t\t\t// in getwork (which we will load), but this is of no consequence to live mining.\n\twire [31:0] target_vw;\t\t// This depends on the pool, variable diff pools will update the target dynamically\n\n\tvirtual_wire # (.PROBE_WIDTH(0), .WIDTH(256), .INSTANCE_ID(\"DAT1\")) data1_vw_blk(.probe(), .source(data1_vw));\n\tvirtual_wire # (.PROBE_WIDTH(0), .WIDTH(256), .INSTANCE_ID(\"DAT2\")) data2_vw_blk(.probe(), .source(data2_vw));\n\tvirtual_wire # (.PROBE_WIDTH(0), .WIDTH(128), .INSTANCE_ID(\"DAT3\")) data3_vw_blk(.probe(), .source(data3_vw));\n\tvirtual_wire # (.PROBE_WIDTH(0), .WIDTH(32), .INSTANCE_ID(\"TARG\")) target_vw_blk(.probe(), .source(target_vw));\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tdata1 <= data1_vw;\n\t\tdata2 <= data2_vw;\n\t\tdata3 <= data3_vw;\n\t\ttarget <= target_vw;\n\tend\n\n\t//// Virtual Wire Output\n\t\n\tvirtual_wire # (.PROBE_WIDTH(32), .WIDTH(0), .INSTANCE_ID(\"GNON\")) golden_nonce_vw_blk (.probe(golden_nonce_out), .source());\n\tvirtual_wire # (.PROBE_WIDTH(32), .WIDTH(0), .INSTANCE_ID(\"NONC\")) nonce_vw_blk (.probe(nonce_out), .source());\n\n\t`endif\n\t\n\n`ifndef NOLEDS\n\t// Optional LED progress indicator\n\talways @(posedge pbkdf_clk) begin\n\t`ifdef INVERTLEDS\n\t\tLEDS_out <= ~nonce_out[15:8];\t\t// Inverted for BeMicro\n\t`else\n\t\tLEDS_out <= nonce_out[15:8];\n\t`endif\n\tend\n`endif\n\nendmodule\n"
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/pbkdfengine.v",
    "content": "/* pbkdfengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`define ICARUS\t\t\t// Comment this out when using the altera virtual_wire interface in ltcminer.v\n\t\n`timescale 1ns/1ps\n\nmodule pbkdfengine\n\t(hash_clk, pbkdf_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce,\n\t\t\tsalsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift);\n\n\tinput hash_clk;\t\t\t// Just drives shift register\n\tinput pbkdf_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\n\toutput [31:0] nonce_out;\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] salsa_dout;\n\toutput [SBITS-1:0] salsa_din;\n\n\tinput salsa_busy, salsa_result;\t// NB hash_clk domain\n\toutput salsa_reset;\n\toutput salsa_start;\n\toutput reg salsa_shift = 1'b0;\t// NB hash_clk domain\n\n\treg [4:0]resetcycles = 4'd0;\n\treg reset = 1'b0;\n\tassign salsa_reset = reset;\t\t// Propagate reset to salsaengine\n\n`ifdef WANTCYCLICRESET\t\t\n\treg [23:0]cycresetcount = 24'd0;\n`endif\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\t// Hard code a 31 cycle reset (NB assumes THREADS=16 in salsaengine, else we need more)\n\t\t// NB hash_clk is faster than pbkdf_clk so the salsaengine will actually be initialised well before\n\t\t// this period ends, but keep to 15 for now as simulation uses equal pbkdf and salsa clock speeds.\n\t\tresetcycles <= resetcycles + 1'd1;\n\t\tif (resetcycles == 0)\n\t\t\treset <= 1'b1;\n\t\tif (resetcycles == 31)\n\t\tbegin\n\t\t\treset <= 1'b0;\n\t\t\tresetcycles <= 31;\n\t\tend\n`ifdef WANTCYCLICRESET\t\t\n\t\t// Cyclical reset every 2_500_000 clocks to ensure salsa pipeline does not drift out of sync\n\t\t// This may be unneccessary if we reset every loadnonce\n\t\t// Actually it seems to do more harm than good, so disabled\n\t\tcycresetcount <= cycresetcount + 1'd1;\n\t\tif (cycresetcount == 2_500_000)\t// 10 per second at 25MHz (adjust as neccessary)\n\t\tbegin\n\t\t\tcycresetcount <= 24'd0;\n\t\t\tresetcycles <= 5'd0;\n\t\tend\n`endif\t\t\n\t\t// Reset on loadnonce (the hash results will be junk anyway since data changes, so no loss of shares)\n\t\tif (loadnonce)\n\t\t\tresetcycles <= 5'd0;\n\tend\n\t\n\t`ifndef ICARUS\n\treg [31:0] nonce_previous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\t`endif\n\n\t`ifndef NOMULTICORE\n\t`ifdef SIM\n\t\treg [27:0] nonce_cnt = 28'h318f;\t// Start point for simulation (NB also define SIM in serial.v)\n\t`else\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t`endif\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\tassign nonce_out = nonce;\n\n\treg [31:0] nonce_sr = 32'd0;\t\t// Nonce is shifted to salsaengine for storage/retrieval (hash_clk domain)\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\treg [2:0] nonce_wait = 3'd0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [2:0] blockcnt = 3'd0;\t\t// Takes values 1..5 for block iteration\n\treg [1023:0] Xbuf = 1024'd0;\t// Shared input/output buffer and shift register (hash_clk domain)\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\tassign salsa_din = Xbuf[1023:1024-SBITS];\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\t\n\t// MixOut is little-endian word format to match scrypt.c so convert back to big-endian\n\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] mix;\n\t\tassign mix = Xbuf[`IDX(i)];\t\t// NB MixOut now shares Xbuf since shifted in/out\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\n\t// Interface control. This should be OK provided the threads remain evenly spaced (hence we reset on loadnonce)\n\t\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\treg Clr_SMixOutRdy = 1'b0;\n\twire Clr_SMixInRdy;\n\twire Set_SMixOutRdy;\n\n\treg [4:0]salsa_busy_d = 0;\t\t\t// Sync to pbkdf_clk domain\n\treg [4:0]salsa_result_d = 0;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\t// Sync to pbkdf_clk domain\n\t\tsalsa_busy_d[0] <= salsa_busy;\n\t\tif (salsa_busy & ~ salsa_busy_d[0])\n\t\t\tsalsa_busy_d[1] <= ~ salsa_busy_d[1];\t\t// Toggle on busy going high\n\t\t\n\t\tsalsa_result_d[0] <= salsa_result;\n\t\tif (salsa_result & ~ salsa_result_d[0])\n\t\t\tsalsa_result_d[1] <= ~ salsa_result_d[1];\t// Toggle on result going high\n\tend\n\t\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tsalsa_busy_d[4:2] <= salsa_busy_d[3:1];\n\t\tsalsa_result_d[4:2] <= salsa_result_d[3:1];\n\t\t\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\t\t\t\n\t\t// CARE there is a race with Set_SMixInRdy, Clr_SMixOutRdy which are set in the FSM\n\t\t// Need to assert reset for several cycles to ensure consistency (acutally use 15 since salsaengine needs more)\n\t\tif (reset)\n\t\tbegin\t\t\t\t\t\t\t// Reset takes priority\n\t\t\tSMixInRdy_state <= 1'b0;\n\t\t\tSMixOutRdy_state <= 1'b0;\n\t\tend\n\tend\n\t\n\tassign Clr_SMixInRdy = SMixInRdy_state & (salsa_busy_d[3] ^ salsa_busy_d[4]);\t\t\t// Clear on transition to busy\n\t\n\tassign Set_SMixOutRdy = ~SMixOutRdy_state & (salsa_result_d[3] ^ salsa_result_d[4]);\t// Set on transition to result\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\tassign salsa_start = SMixInRdy;\n\t\t\n\t// Clock crossing flags for shift register control (span pbkdf_clk, hash_clk domains)\n\treg [3:0]Xbuf_load_request = 1'b0;\n\treg [3:0]shift_request =  1'b0;\n\treg [3:0]shift_acknowledge = 1'b0;\n\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz)\n\t\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_NONCE=22, S_SHIFT_IN=41, S_SHIFT_OUT=42,\t\t\t\t// Direction relative to salsa unit\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\treg start_output = 0;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\n\t\tshift_acknowledge[3:1] <= shift_acknowledge[2:0];\t// Clock crossing\n\n\t\t`ifdef ICARUS\n\t\tif (loadnonce)\t\t\t\t// Separate clock domains means comparison is unsafe\n\t\t`else\n\t\tif (loadnonce || (nonce_previous_load != data3[127:96]))\n\t\t`endif\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_previous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\t`ifndef ICARUS\n\t\t\tnonce_previous_load <= data3[127:96];\n\t\t\t`endif\n\t\tend\n\t\t\n\t\tif (reset == 1'b1)\n\t\tbegin\n\t\t\tstate <= S_IDLE;\n\t\t\tstart_output <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tif (SMixOutRdy & ~start_output)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\t// Request shifter to start\n\t\t\t\t\t\tstate <= S_SHIFT_OUT;\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (start_output ||\t// Process output\n\t\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'b0;\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\t\tblockcnt <= 3'd1;\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_sr : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\t\t\n\t\t\t\tS_B6: begin\n\t\t\t\t\t\tkhash <= tx_hash;\t\t// Save temporarily (for Xbuf)\n\n\t\t\t\t\t\tXbuf_load_request[0] <= ~Xbuf_load_request[0];\t// NB also loads nonce_sr\n\n\t\t\t\t\t\tif (blockcnt == 3'd5)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tnonce_wait <= 3'd7;\n\t\t\t\t\t\t\tstate <= S_NONCE;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_NONCE: begin\n\t\t\t\t\t\t// Need to delay a few clocks for Xbuf_load_request to complete\n\t\t\t\t\t\tnonce_wait <= nonce_wait - 1'd1;\n\t\t\t\t\t\tif (nonce_wait == 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 1'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 1'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\n\t\t\t\t\t\t\tstate <= S_SHIFT_IN;\n\t\t\t\t\t\tend\n\t\t\t\t\n\t\t\t\tend\n\t\t\t\tS_SHIFT_IN: begin\t\t\t\t\t\t\t// Shifting from PBKDF2_SHA256 to salsa\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tSet_SMixInRdy <= 1'd1;\t\t\t\t// Flag salsa to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_SHIFT_OUT: begin\t\t\t\t\t\t\t// Shifting from salsa to PBKDF2_SHA256\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'd1;\t\t\t\t// Flag self to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_sr;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n\tend\n\n\t// Shift register control - NB hash_clk domain\n\t\n\treg\t[10:0]shift_count = 11'd0;\t// hash_clk domain\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tif (reset)\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b0;\n\t\t\tshift_count <= 11'd0;\n\t\tend\n\n\t\t// Clock crossing logic\n\t\tXbuf_load_request[3:1] <= Xbuf_load_request[2:0];\n\t\tif (Xbuf_load_request[3] != Xbuf_load_request[2])\n\t\tbegin\n\t\t\t// Shift output into X buffer from MSB->LSB\n\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\tXbuf[1023:768] <= khash;\n\n\t\t\tnonce_sr <= nonce;\t// Loaded several times, but of no consequence\n\t\tend\n\t\t\n\t\tshift_request[3:1] <= shift_request[2:0];\n\t\tif (shift_request[3] != shift_request[2])\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b1;\n\t\tend\n\n\t\tif (salsa_shift)\n\t\tbegin\n\t\t\tshift_count <= shift_count + 1'b1;\n\t\t\tXbuf <= { Xbuf[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], salsa_dout };\n\t\tend\n\t\t\n\t\tif (shift_count == (1024+32)/SBITS-1)\n\t\tbegin\n\t\t\tshift_acknowledge[0] = ~shift_acknowledge[0];\n\t\t\tshift_count <= 0;\n\t\t\tsalsa_shift <= 0;\n\t\tend\n\tend\n\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(pbkdf_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\nendmodule"
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/salsa_slowsixteen.v",
    "content": "/* salsa_slowsixteen.v\n*\n* Copyright (c) 2013 kramble\n* Derived from scrypt.c Copyright 2009 Colin Percival, 2011 ArtForz\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\nmodule salsa (clk, B, Bx, Bo, X0out, Xaddr);\n\n// Latency 16 clock cycles, approx 20nS propagation delay (SLOW!)\n\ninput clk;\n// input feedback;\ninput [511:0]B;\ninput [511:0]Bx;\n// output reg [511:0]Bo;\t// Output is registered\noutput [511:0]Bo;\t\t\t// Output is async\noutput [511:0]X0out;\t\t// Becomes new X0\noutput [9:0] Xaddr;\nwire [9:0] xa1, xa2, xa3, xa4, ya1, ya2, ya3, ya4;\n\nreg [511:0]x1d1, x1d1a;\nreg [511:0]x1d2, x1d2a;\nreg [511:0]x1d3, x1d3a;\nreg [511:0]x1d4, x1d4a;\n\nreg [511:0]Xod1, Xod1a;\nreg [511:0]Xod2, Xod2a;\nreg [511:0]Xod3, Xod3a;\nreg [511:0]Xod4, X0out;\n\nreg [511:0]xxd1, xxd1a;\nreg [511:0]xxd2, xxd2a;\nreg [511:0]xxd3, xxd3a;\nreg [511:0]xxd4, xxd4a;\n\nreg [511:0]yyd1, yyd1a;\nreg [511:0]yyd2, yyd2a;\nreg [511:0]yyd3, yyd3a;\nreg [511:0]yyd4, yyd4a;\n\nwire [511:0]xx;\t\t\t// Initial xor\nwire [511:0]x1;\t\t\t// Salasa core outputs\nwire [511:0]x2;\nwire [511:0]x3;\nwire [511:0]xr;\nwire [511:0]Xo;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsax1 (clk, xx, x1, xa1);\nsalsa_core salsax2 (clk, x1, x2, xa2);\nsalsa_core salsax3 (clk, x2, x3, xa3);\nsalsa_core salsax4 (clk, x3, xr, xa4);\n\nwire [511:0]yy;\t\t\t// Initial xor\nwire [511:0]y1;\t\t\t// Salasa core outputs\nwire [511:0]y2;\nwire [511:0]y3;\nwire [511:0]yr;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsay1 (clk, yy, y1, ya1);\nsalsa_core salsay2 (clk, y1, y2, ya2);\nsalsa_core salsay3 (clk, y2, y3, ya3);\nsalsa_core salsay4 (clk, y3, yr, ya4);\n\nassign Xaddr = yyd4[9:0] + ya4;\n\ngenvar i;\ngenerate\n\tfor (i = 0; i < 16; i = i + 1) begin : XX\n\t\t// Initial XOR. NB this adds to the propagation delay of the first salsa, may want register it.\n\t\tassign xx[`IDX(i)] = B[`IDX(i)] ^ Bx[`IDX(i)];\n\t\tassign Xo[`IDX(i)] = xxd4a[`IDX(i)] + xr[`IDX(i)];\n\t\tassign yy[`IDX(i)] = x1d4a[`IDX(i)] ^ Xo[`IDX(i)];\n\t\tassign Bo[`IDX(i)] = yyd4a[`IDX(i)] + yr[`IDX(i)];\t// Async output\n\tend\nendgenerate\n\nalways @ (posedge clk)\nbegin\n\tx1d1 <= Bx;\n\tx1d1a <= x1d1;\n\tx1d2 <= x1d1a;\n\tx1d2a <= x1d2;\n\tx1d3 <= x1d2a;\n\tx1d3a <= x1d3;\n\tx1d4 <= x1d3a;\n\tx1d4a <= x1d4;\n\tXod1 <= Xo;\n\tXod1a <= Xod1;\n\tXod2 <= Xod1a;\n\tXod2a <= Xod2;\n\tXod3 <= Xod2a;\n\tXod3a <= Xod3;\n\tXod4 <= Xod3a;\n\tX0out <= Xod4;\t// We output this to become new X0\n\n\txxd1 <= xx;\n\txxd1a <= xxd1;\n\txxd2 <= xxd1a;\n\txxd2a <= xxd2;\n\txxd3 <= xxd2a;\n\txxd3a <= xxd3;\n\txxd4 <= xxd3a;\n\txxd4a <= xxd4;\n\n\tyyd1 <= yy;\n\tyyd1a <= yyd1;\n\tyyd2 <= yyd1a;\n\tyyd2a <= yyd2;\n\tyyd3 <= yyd2a;\n\tyyd3a <= yyd3;\n\tyyd4 <= yyd3a;\n\tyyd4a <= yyd4;\n\nend\n\nendmodule\n\nmodule salsa_core (clk, xx, out, Xaddr);\n\ninput clk;\ninput [511:0]xx;\noutput reg [511:0]out;\t\t// Output is registered\noutput [9:0] Xaddr;\t\t\t// Address output unregistered\n\n// This is clunky due to my lack of verilog skills but it works so elegance can come later\n\nwire [31:0]c00;\t\t\t// Column results\nwire [31:0]c01;\nwire [31:0]c02;\nwire [31:0]c03;\nwire [31:0]c04;\nwire [31:0]c05;\nwire [31:0]c06;\nwire [31:0]c07;\nwire [31:0]c08;\nwire [31:0]c09;\nwire [31:0]c10;\nwire [31:0]c11;\nwire [31:0]c12;\nwire [31:0]c13;\nwire [31:0]c14;\nwire [31:0]c15;\n\nwire [31:0]r00;\t\t\t// Row results\nwire [31:0]r01;\nwire [31:0]r02;\nwire [31:0]r03;\nwire [31:0]r04;\nwire [31:0]r05;\nwire [31:0]r06;\nwire [31:0]r07;\nwire [31:0]r08;\nwire [31:0]r09;\nwire [31:0]r10;\nwire [31:0]r11;\nwire [31:0]r12;\nwire [31:0]r13;\nwire [31:0]r14;\nwire [31:0]r15;\n\nwire [31:0]c00s;\t\t\t// Column sums\nwire [31:0]c01s;\nwire [31:0]c02s;\nwire [31:0]c03s;\nwire [31:0]c04s;\nwire [31:0]c05s;\nwire [31:0]c06s;\nwire [31:0]c07s;\nwire [31:0]c08s;\nwire [31:0]c09s;\nwire [31:0]c10s;\nwire [31:0]c11s;\nwire [31:0]c12s;\nwire [31:0]c13s;\nwire [31:0]c14s;\nwire [31:0]c15s;\n\nwire [31:0]r00s;\t\t\t// Row sums\nwire [31:0]r01s;\nwire [31:0]r02s;\nwire [31:0]r03s;\nwire [31:0]r04s;\nwire [31:0]r05s;\nwire [31:0]r06s;\nwire [31:0]r07s;\nwire [31:0]r08s;\nwire [31:0]r09s;\nwire [31:0]r10s;\nwire [31:0]r11s;\nwire [31:0]r12s;\nwire [31:0]r13s;\nwire [31:0]r14s;\nwire [31:0]r15s;\n\nreg [31:0]c00d;\t\t\t// Column results registered\nreg [31:0]c01d;\nreg [31:0]c02d;\nreg [31:0]c03d;\nreg [31:0]c04d;\nreg [31:0]c05d;\nreg [31:0]c06d;\nreg [31:0]c07d;\nreg [31:0]c08d;\nreg [31:0]c09d;\nreg [31:0]c10d;\nreg [31:0]c11d;\nreg [31:0]c12d;\nreg [31:0]c13d;\nreg [31:0]c14d;\nreg [31:0]c15d;\n\n/* From scrypt.c\n\n#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))\n\tfor (i = 0; i < 8; i += 2) {\n\t\t// Operate on columns\n\t\tx04 ^= R(x00+x12, 7);\tx09 ^= R(x05+x01, 7);\tx14 ^= R(x10+x06, 7);\tx03 ^= R(x15+x11, 7);\n\t\tx08 ^= R(x04+x00, 9);\tx13 ^= R(x09+x05, 9);\tx02 ^= R(x14+x10, 9);\tx07 ^= R(x03+x15, 9);\n\t\tx12 ^= R(x08+x04,13);\tx01 ^= R(x13+x09,13);\tx06 ^= R(x02+x14,13);\tx11 ^= R(x07+x03,13);\n\t\tx00 ^= R(x12+x08,18);\tx05 ^= R(x01+x13,18);\tx10 ^= R(x06+x02,18);\tx15 ^= R(x11+x07,18);\n\n\t\t// Operate on rows\n\t\tx01 ^= R(x00+x03, 7);\tx06 ^= R(x05+x04, 7);\tx11 ^= R(x10+x09, 7);\tx12 ^= R(x15+x14, 7);\n\t\tx02 ^= R(x01+x00, 9);\tx07 ^= R(x06+x05, 9);\tx08 ^= R(x11+x10, 9);\tx13 ^= R(x12+x15, 9);\n\t\tx03 ^= R(x02+x01,13);\tx04 ^= R(x07+x06,13);\tx09 ^= R(x08+x11,13);\tx14 ^= R(x13+x12,13);\n\t\tx00 ^= R(x03+x02,18);\tx05 ^= R(x04+x07,18);\tx10 ^= R(x09+x08,18);\tx15 ^= R(x14+x13,18);\n\t}\n*/\n\n// cols\n\nassign c04s = xx[`IDX(0)] + xx[`IDX(12)];\nassign c04 = xx[`IDX(4)] ^ { c04s[24:0], c04s[31:25] };\nassign c09s = xx[`IDX(5)] + xx[`IDX(1)];\nassign c09 = xx[`IDX(9)] ^ { c09s[24:0], c09s[31:25] };\nassign c14s = xx[`IDX(10)] + xx[`IDX(6)];\nassign c14 = xx[`IDX(14)] ^ { c14s[24:0], c14s[31:25] };\nassign c03s = xx[`IDX(15)] + xx[`IDX(11)];\nassign c03 = xx[`IDX(03)] ^ { c03s[24:0], c03s[31:25] };\n\nassign c08s = c04 + xx[`IDX(0)];\nassign c08 = xx[`IDX(8)] ^ { c08s[22:0], c08s[31:23] };\nassign c13s = c09 + xx[`IDX(5)];\nassign c13 = xx[`IDX(13)] ^ { c13s[22:0], c13s[31:23] };\nassign c02s = c14 + xx[`IDX(10)];\nassign c02 = xx[`IDX(2)] ^ { c02s[22:0], c02s[31:23] };\nassign c07s = c03 + xx[`IDX(15)];\nassign c07 = xx[`IDX(7)] ^ { c07s[22:0], c07s[31:23] };\n\nassign c12s = c08 + c04;\nassign c12 = xx[`IDX(12)] ^ { c12s[18:0], c12s[31:19] };\nassign c01s = c13 + c09;\nassign c01 = xx[`IDX(1)] ^ { c01s[18:0], c01s[31:19] };\nassign c06s = c02 + c14;\nassign c06 = xx[`IDX(6)] ^ { c06s[18:0], c06s[31:19] };\nassign c11s = c07 + c03;\nassign c11 = xx[`IDX(11)] ^ { c11s[18:0], c11s[31:19] };\n\nassign c00s = c12 + c08;\nassign c00 = xx[`IDX(0)] ^ { c00s[13:0], c00s[31:14] };\nassign c05s = c01 + c13;\nassign c05 = xx[`IDX(5)] ^ { c05s[13:0], c05s[31:14] };\nassign c10s = c06 + c02;\nassign c10 = xx[`IDX(10)] ^ { c10s[13:0], c10s[31:14] };\nassign c15s = c11 + c07;\nassign c15 = xx[`IDX(15)] ^ { c15s[13:0], c15s[31:14] };\n\n// rows\n\nassign r01s = c00d + c03d;\nassign r01 = c01d ^ { r01s[24:0], r01s[31:25] };\nassign r06s = c05d + c04d;\nassign r06 = c06d ^ { r06s[24:0], r06s[31:25] };\nassign r11s = c10d + c09d;\nassign r11 = c11d ^ { r11s[24:0], r11s[31:25] };\nassign r12s = c15d + c14d;\nassign r12 = c12d ^ { r12s[24:0], r12s[31:25] };\n\nassign r02s = r01 + c00d;\nassign r02 = c02d ^ { r02s[22:0], r02s[31:23] };\nassign r07s = r06 + c05d;\nassign r07 = c07d ^ { r07s[22:0], r07s[31:23] };\nassign r08s = r11 + c10d;\nassign r08 = c08d ^ { r08s[22:0], r08s[31:23] };\nassign r13s = r12 + c15d;\nassign r13 = c13d ^ { r13s[22:0], r13s[31:23] };\n\nassign r03s = r02 + r01;\nassign r03 = c03d ^ { r03s[18:0], r03s[31:19] };\nassign r04s = r07 + r06;\nassign r04 = c04d ^ { r04s[18:0], r04s[31:19] };\nassign r09s = r08 + r11;\nassign r09 = c09d ^ { r09s[18:0], r09s[31:19] };\nassign r14s = r13 + r12;\nassign r14 = c14d ^ { r14s[18:0], r14s[31:19] };\n\nassign r00s = r03 + r02;\nassign r00 = c00d ^ { r00s[13:0], r00s[31:14] };\nassign r05s = r04 + r07;\nassign r05 = c05d ^ { r05s[13:0], r05s[31:14] };\nassign r10s = r09 + r08;\nassign r10 = c10d ^ { r10s[13:0], r10s[31:14] };\nassign r15s = r14 + r13;\nassign r15 = c15d ^ { r15s[13:0], r15s[31:14] };\n\nwire [511:0]xo;\t\t\t// Rename row results\nassign xo = { r15, r14, r13, r12, r11, r10, r09, r08, r07, r06, r05, r04, r03, r02, r01, r00 };\n\nassign Xaddr = xo[9:0];\t// Unregistered output\n\nalways @ (posedge clk)\nbegin\n\tc00d <= c00;\n\tc01d <= c01;\n\tc02d <= c02;\n\tc03d <= c03;\n\tc04d <= c04;\n\tc05d <= c05;\n\tc06d <= c06;\n\tc07d <= c07;\n\tc08d <= c08;\n\tc09d <= c09;\n\tc10d <= c10;\n\tc11d <= c11;\n\tc12d <= c12;\n\tc13d <= c13;\n\tc14d <= c14;\n\tc15d <= c15;\n\tout <= xo;\t\t// Registered output\nend\n\nendmodule\n"
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/salsaengine.v",
    "content": "/* salsaengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n// NB HALFRAM no longer applies, configure via parameters ADDRBITS, THREADS\n\n// Bracket this config option in SIM so we don't accidentally leave it set in a live build\n`ifdef SIM\n//`define ONETHREAD\t// Start one thread only (for SIMULATION less confusing and faster startup)\n`endif\n\n`timescale 1ns/1ps\n\nmodule salsaengine (hash_clk, reset, din, dout, shift, start, busy, result );\n\n\n\tinput hash_clk;\n\tinput reset;\t// NB pbkdf_clk domain (need a long reset (at least THREADS+4) to initialize correctly, this is done in pbkdfengine (15 cycles)\n\tinput shift;\n\tinput start;\t// NB pbkdf_clk domain\n\toutput busy;\n\toutput reg result = 1'b0;\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] din;\n\toutput [SBITS-1:0] dout;\n\n\t// Configure ADDRBITS to allocate RAM for core (automatically sets LOOKAHEAD_GAP)\n\t// NB do not use ADDRBITS > 13 for THREADS=8 since this corresponds to more than a full scratchpad\n\n\t// These settings are now overriden in ltcminer_icarus.v determined by LOCAL_MINERS ...\n\t// parameter ADDRBITS = 13;\t// 8MBit RAM allocated to core, full scratchpad (will not fit LX150)\n\tparameter ADDRBITS = 12;\t// 4MBit RAM allocated to core, half scratchpad\n\t// parameter ADDRBITS = 11;\t// 2MBit RAM allocated to core, quarter scratchpad\n\t// parameter ADDRBITS = 10;\t// 1MBit RAM allocated to core, eighth scratchpad\n\n\t// Do not change THREADS - this must match the salsa pipeline (code is untested for other values)\n\tparameter THREADS = 16;\t\t// NB Phase has THREADS+1 cycles\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n\tparameter THREADS_BITS = clog2(THREADS);\n\t\n\t// Workaround for range-reversal error in inactive code when ADDRBITS=13\n\tparameter ADDRBITSX = (ADDRBITS == 13) ? ADDRBITS-1 : ADDRBITS;\n\n\treg [THREADS_BITS:0]phase = 0;\n\treg [THREADS_BITS:0]phase_d = THREADS+1;\n\treg reset_d=0, fsmreset=0, start_d=0, fsmstart=0;\n\n\talways @ (posedge hash_clk)\t\t// Phase control and sync\n\tbegin\n\t\tphase <= (phase == THREADS) ? 0 : phase + 1;\n\t\tphase_d <= phase;\n\t\treset_d <= reset;\t\t\t// Synchronise to hash_clk domain\n\t\tfsmreset <= reset_d;\n\t\tstart_d <= start;\n\t\tfsmstart <= start_d;\n\tend\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\tparameter XSnull = 0, XSload = 1, XSmix = 2, XSram = 4;\t\t\t// One-hot since these map directly to mux contrls\n\treg [2:0] XCtl = XSnull;\n\n\tparameter R_IDLE=0, R_START=1, R_WRITE=2, R_MIX=3, R_INT=4, R_WAIT=5;\n\treg [2:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs\n\treg addrsourceMix = 1'b0;\n\treg datasourceLoad = 1'b0;\n\treg addrsourceSave = 1'b0;\n\treg resultsourceRam = 1'b0;\n\treg xoren = 1'b1;\n\treg [THREADS_BITS+1:0] intcycles = 0;\t// Number of interpolation cycles required ... How many do we need? Say THREADS_BITS+1\n\n\twire [511:0] Xmix;\n\treg [511:0] X0;\n\treg [511:0] X1;\n\twire [511:0] X0in;\n\twire [511:0] X1in;\n\twire [511:0] X0out;\n\treg [1023:0] salsaShiftReg;\n\treg [31:0] nonce_sr;\t\t\t// In series with salsaShiftReg\n\tassign dout = salsaShiftReg[1023:1024-SBITS];\n\n\t// sstate is implemented in ram (alternatively could use a rotating shift register)\n\treg [THREADS_BITS+30:0] sstate [THREADS-1:0];\t\t// NB initialized via a long reset (see pbkdfengine)\n\t// List components of sstate here for ease of maintenance ...\n\twire [2:0] mstate_in;\n\twire [10:0] cycle_in;\n\twire [9:0] writeaddr_in;\n\twire doneROM_in;\n\twire addrsourceMix_in;\n\twire addrsourceSave_in;\n\twire [THREADS_BITS+1:0] intcycles_in;\t\t\t\t// How many do we need? Say THREADS_BITS+1\n\n\twire [9:0] writeaddr_next = writeaddr_in + 10'd1;\n\n\treg [31:0] snonce [THREADS-1:0];\t\t\t\t\t// Nonce store. Note bidirectional loading below, this will either implement\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// as registers or dual-port ram, so do NOT integrate with sstate.\n\t\n\t// NB no busy_in or result_in as these flag are NOT saved on a per-thread basis\n\n\t// Convert salsaShiftReg to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = salsaShiftReg[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\tend\n\tendgenerate\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of RAM size\n\treg [9:0] writeaddr = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\twire [9:0] Xaddr;\n\twire [ADDRBITS-1:0]rd_addr;\n\twire [ADDRBITS-1:0]wr_addr1;\n\twire [ADDRBITS-1:0]wr_addr2;\n\twire [ADDRBITS-1:0]wr_addr3;\n\twire [ADDRBITS-1:0]wr_addr4;\n\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\treg ram_wren = 1'b0;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\t// Top ram address is reserved for X0Save/X1save, so adjust\n\t\n\twire [15:0] memtop = 16'hfffe;\t// One less than the top memory location (per THREAD bank)\n\t\n\twire [ADDRBITS-THREADS_BITS-1:0] adj_addr;\n\n\t// HMMM This is BROKEN in Quartus ...\n/*\t\n\tif (ADDRBITS < 13)\n\t\tassign adj_addr = (Xaddr[9:THREADS_BITS+10-ADDRBITS] == memtop[9:THREADS_BITS+10-ADDRBITS]) ?\n\t\t\t\t\t\t\tmemtop[ADDRBITS-THREADS_BITS-1:0] : Xaddr[9:THREADS_BITS+10-ADDRBITS];\n\telse\n\t\tassign adj_addr = Xaddr;\n*/\n\tassign adj_addr = (Xaddr[9:THREADS_BITS+10-ADDRBITS] == memtop[9:THREADS_BITS+10-ADDRBITS]) ?\n\t\t\t\t\t\tmemtop[ADDRBITS-THREADS_BITS-1:0] : Xaddr[9:THREADS_BITS+10-ADDRBITS];\n\n\twire [THREADS_BITS-1:0] phase_addr;\n\tassign phase_addr = phase[THREADS_BITS-1:0];\n\n\t// TODO can we remove the +1 and adjust the wr_addr to use the same prefix via phase_d?\n\tassign rd_addr = { phase_addr+1, addrsourceSave_in ? memtop[ADDRBITS-THREADS_BITS:1] : adj_addr };\t// LSB are ignored\n\t\t\n\twire [9:0] writeaddr_adj = addrsourceMix ? memtop[10:1] : writeaddr;\n\t\n\tassign wr_addr1 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\tassign wr_addr2 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\tassign wr_addr3 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\tassign wr_addr4 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\n\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\n\treg [ADDRBITS-1:0] rd_addr_z_1 = 0;\n\treg [ADDRBITS-1:0] rd_addr_z_2 = 0;\n\treg [ADDRBITS-1:0] rd_addr_z_3 = 0;\n\treg [ADDRBITS-1:0] rd_addr_z_4 = 0;\n\twire [ADDRBITS-1:0] rd_addr1 = rd_addr | rd_addr_z_1;\n\twire [ADDRBITS-1:0] rd_addr2 = rd_addr | rd_addr_z_2;\n\twire [ADDRBITS-1:0] rd_addr3 = rd_addr | rd_addr_z_3;\n\twire [ADDRBITS-1:0] rd_addr4 = rd_addr | rd_addr_z_4;\n\t\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (rd_addr1, wr_addr1, ram_clk, ram1_din, ram_wren, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (rd_addr2, wr_addr2, ram_clk, ram2_din, ram_wren, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (rd_addr3, wr_addr3, ram_clk, ram3_din, ram_wren, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (rd_addr4, wr_addr4, ram_clk, ram4_din, ram_wren, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = datasourceLoad ? X : { Xmix, X0out};\t// Registered input\n\t\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, X0, X1, Xmix, X0out, Xaddr);\n\n\t// Main multiplexer\n\twire [511:0] Zbits;\n\tassign Zbits = {512{xoren}};\t\t// xoren enables xor from ram (else we load from ram)\n\t\n\t// With luck the synthesizer will interpret this correctly as one-hot control ...\n\n\t// DEBUG using default state of 0 for XSnull so as to show up issues with preserved values (previously held value X0/X1)\n\t// assign X0in = (XCtl==XSmix) ? X0out : (XCtl==XSram) ? (X0out & Zbits) ^ ramout[511:0] : (XCtl==XSload) ? X[511:0] : 0;\n\t// assign X1in = (XCtl==XSmix) ? Xmix : (XCtl==XSram) ? (Xmix & Zbits) ^ ramout[1023:512] : (XCtl==XSload) ? X[1023:512] : 0;\n\t\n\t// Now using explicit control signals (rather than relying on synthesizer to map correctly)\n\t// XSMix is now the default (XSnull is unused as this mapped onto zero in the DEBUG version above) - TODO amend FSM accordingly\n\tassign X0in =  XCtl[2] ? (X0out & Zbits) ^ ramout[511:0] : XCtl[0] ? X[511:0] : X0out;\n\tassign X1in =  XCtl[2] ? (Xmix & Zbits) ^ ramout[1023:512] : XCtl[0] ? X[1023:512] : Xmix;\n\n\t// Salsa FSM - TODO may want to move this into a separate function (for floorplanning), see hashvariant-C\n\n\t// Hold separate state for each thread (a bit of a kludge to avoid rewriting FSM from scratch)\n\t// NB must ensure shift and result do NOT overlap by carefully controlling timing of start signal\n\t// NB Phase has THREADS+1 cycles, but we do not save the state for (phase==THREADS) as it is never active\n\n\tassign { mstate_in, writeaddr_in, cycle_in, doneROM_in, addrsourceMix_in, addrsourceSave_in, intcycles_in} =\n\t\t\t\t(phase == THREADS ) ? 0 : sstate[phase];\t\n\t\n\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\n\treg busy_flag = 1'b0;\n\t\n`ifdef ONETHREAD\n\t// TEST CONTROLLER ... just allow a single thread to run (busy is currently a common flag)\n\t// NB the thread automatically restarts after it completes, so its a slight misnomer to say it starts once.\n\treg start_once = 1'b0;\n\twire start_flag;\n\tassign start_flag = fsmstart & ~start_once;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine\n`else\n\t// NB start_flag only has effect when a thread is at R_IDLE, ie after reset, normally a thread will automatically\n\t// restart on completion. We need to spread the R_IDLE starts evenly to ensure proper ooperation. NB the pbkdf\n\t// engine requires busy and result, but this  looks alter itself in the salsa FSM, even though these are global\n\t// flags. Reset periodically (on loadnonce in pbkdfengine) to ensure it stays in sync.\n\treg [15:0] start_count = 0;\n\t// TODO automatic configuration (currently assumes THREADS 8 or 16, and ADDRBITS 12,11,10 calculated as follows...)\n\t// For THREADS=8, lookup_gap=2 salsa takes on average 9*(1024+(1024*1.5)) = 23040 clocks, generically 9*1024*(lookup_gap/2+1.5)\n\t// For THREADS=16, use 17*1024*(lookup_gap/2+1.5), where lookupgap is double that for THREADS=8\n\tparameter START_INTERVAL = (THREADS==16) ?\t((ADDRBITS==12) ? 60928 : (ADDRBITS==11) ? 95744 : 165376) / THREADS :\t// 16 threads\n\t\t\t\t\t\t\t\t\t\t\t\t((ADDRBITS==12) ? 23040 : (ADDRBITS==11) ? 36864 :  50688) / THREADS ;\t//  8 threads\n\treg start_flag = 1'b0;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine - this will toggle on transtion through R_START\n`endif\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tX0 <= X0in;\n\t\tX1 <= X1in;\n\t\t\n\t\tif (phase_d != THREADS)\n\t\t\tsstate[phase_d] <= fsmreset ? 0 : { mstate, writeaddr, cycle, doneROM, addrsourceMix, addrsourceSave, intcycles };\n\n\t\tmstate <= mstate_in;\t\t// Set defaults (overridden below as necessary)\n\t\twriteaddr <= writeaddr_in;\n\t\tcycle <= cycle_in;\n\t\tintcycles <= intcycles_in;\n\t\tdoneROM <= doneROM_in;\n\t\taddrsourceMix <= addrsourceMix_in;\n\t\taddrsourceSave <= addrsourceSave_in;\t\t// Overwritten below, but addrsourceSave_in is used above\n\t\t\n\t\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\trd_addr_z_1 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_2 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_3 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_4 <= {ADDRBITS{fsmreset}};\n\t\t\n\t\tXCtl <= XSnull;\t\t\t\t// Default states\n\t\taddrsourceSave <= 0;\t\t// NB addrsourceSave_in is the active control so this DOES need to be in sstate\n\t\tdatasourceLoad <= 0;\t\t// Does not need to be saved in sstate\n\t\tresultsourceRam <= 0;\t\t// Does not need to be saved in sstate\n\t\tram_wren <= 0;\n\t\txoren <= 1;\n\t\t\n\t\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\t\t`ifdef ONETHREAD\n\t\tif (fsmstart && phase!=THREADS)\n\t\t\tstart_once <= 1'b1;\n\t\tif (fsmreset)\n\t\t\tstart_once <= 1'b0;\n\t\t`else\n\t\tstart_count <= start_count + 1;\n\t\t// start_flag <= 1'b0;\t\t\t// Done below when we transition out of R_IDLE\n\t\tif (fsmreset || start_count == START_INTERVAL)\n\t\tbegin\n\t\t\tstart_count <= 0;\n\t\t\tif (~fsmreset && fsmstart)\n\t\t\t\tstart_flag <= 1'b1;\n\t\tend\n\t\t`endif\n\t\t\n\t\t// Could use explicit mux for this ...\n\t\tif (shift)\n\t\tbegin\n\t\t\tsalsaShiftReg <= { salsaShiftReg[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], din};\n\t\tend\n\t\telse\n\t\tif (XCtl==XSload && phase_d != THREADS)\t\t// Set at end of previous hash - this is executed regardless of phase\t\t\n\t\tbegin\n\t\t\tsalsaShiftReg <= resultsourceRam ? ramout : { Xmix, X0out };\t// Simultaneously with XSload\n\t\t\tnonce_sr <= snonce[phase_d];\t\t\t\t\t\t\t\t\t// NB bidirectional load\n\t\t\tsnonce[phase_d] <= nonce_sr;\n\t\tend\n\t\t\n\t\tif (fsmreset == 1'b1)\n\t\tbegin\n\t\t\tmstate <= R_IDLE;\t\t// This will propagate to all sstate slots as we hold reset for 10 cycles\n\t\t\tbusy_flag <= 1'b0;\n\t\t\tresult <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate_in)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\t// R_IDLE only applies after reset. Normally each thread will reenter at S_START and\n\t\t\t\t\t// assumes that input data is waiting (this relies on the threads being started evenly,\n\t\t\t\t\t// hence the interface FSM at the top of this file)\n\t\t\t\t\tif (phase!=THREADS && start_flag)\t// Ensure (phase==THREADS) slot is never active\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSload;\t\t\t// First time only (normally done at end of previous salsa cycle=1023)\n\t\t\t\t\t\t`ifndef ONETHREAD\n\t\t\t\t\t\t\tstart_flag <= 1'b0;\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t\t// Toggle the busy flag low to ack pbkdfengine (its usually already set\n\t\t\t\t\t\t\t\t\t\t\t\t// since other threads are running)\n\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\tdatasourceLoad <= 1'b1;\n\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tmstate <= R_START;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_START: begin\t\t\t\t\t\t// Reentry point after thread completion. ASSUMES new data is ready.\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\t\twriteaddr <= writeaddr_next;\n\t\t\t\t\t\tcycle <= 0;\n\t\t\t\t\t\tif (ADDRBITS == 13)\n\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Full scratchpad needs to write to addr=001 next cycle\n\t\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\t\tbusy_flag <= 1'b1;\n\t\t\t\t\t\tresult <= 1'b0;\n\t\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\t\tend\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\twriteaddr <= writeaddr_next;\n\t\t\t\t\tif (writeaddr_in==1022)\n\t\t\t\t\t\tdoneROM <= 1'b1;\t\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\telse\n\t\t\t\t\tif (~doneROM_in)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\t\tram_wren <= ~|writeaddr_next[THREADS_BITS+9-ADDRBITSX:0];\t// Only write non-interpolated addresses\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\tend\n\t\t\t\t\t\n\t\t\t\t\tif (doneROM_in)\n\t\t\t\t\tbegin\n\t\t\t\t\t\taddrsourceMix <= 1'b1;\t\t// Remains set for duration of R_MIX\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t// Need this to cover the case of the initial read being interpolated\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_MIX\n\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\tif ( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:THREADS_BITS+10-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr[THREADS_BITS+9-ADDRBITSX:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[THREADS_BITS+9-ADDRBITSX:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\tcycle <= cycle_in + 11'd1;\n\t\t\t\t\tif (cycle_in==1023)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t// Will hold at 0 for 9 clocks until set at R_START\n\t\t\t\t\t\tif (fsmstart)\t\t\t// Check data input is ready\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXCtl <= XSload;\t\t// Initial load else we overwrite input NB This is\n\t\t\t\t\t\t\t\t\t\t\t\t// executed on the next cycle, regardless of phase\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\tmstate <= R_START;\t\t// Restart immediately\n\t\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\t\tdatasourceLoad <= 1'b1;\n\t\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// mstate <= R_IDLE;\t\t// Wait for start_flag\n\t\t\t\t\t\t\tmstate <= R_WAIT;\n\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Save result\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_WRITE\n\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\tif ( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:THREADS_BITS+10-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr[THREADS_BITS+9-ADDRBITSX:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[THREADS_BITS+9-ADDRBITSX:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tR_WAIT: begin\n\t\t\t\t\t\tif (fsmstart)\t\t\t// Check data input is ready\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXCtl <= XSload;\t\t// Initial load else we overwrite input NB This is\n\t\t\t\t\t\t\t\t\t\t\t\t// executed on the next cycle, regardless of phase\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\tmstate <= R_START;\t\t// Restart immediately\n\t\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\t\tdatasourceLoad <= 1'b1;\n\t\t\t\t\t\t\tresultsourceRam <= 1'b1;\n\t\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\tend\n\t\t\t\t\n\t\t\t\tR_INT: begin\n\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\tintcycles <= intcycles_in - 1;\n\t\t\t\t\tif (intcycles_in==2)\n\t\t\t\t\t\taddrsourceSave <= 1'b1;\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\tif (intcycles_in==1)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Setup to XOR from saved X0/X1 in ram at next cycle\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\tend\n\t\t\t\t\t// Else mstate remains at R_INT so we continue interpolating\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (mstate==R_MIX)\n\t\t$display (\"phase %d cycle %d Xmix %08x\\n\", phase, cycle-1, Xmix[511:480]);\n`endif\n\tend\t// always @(posedge hash_clk)\nendmodule"
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/sha-256-functions.v",
    "content": "/*\n*\n* Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n*\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n\n`timescale 1ns/1ps\n\nmodule e0 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y = {x[1:0],x[31:2]} ^ {x[12:0],x[31:13]} ^ {x[21:0],x[31:22]};\n\nendmodule\n\n\nmodule e1 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y = {x[5:0],x[31:6]} ^ {x[10:0],x[31:11]} ^ {x[24:0],x[31:25]};\n\nendmodule\n\n\nmodule ch (x, y, z, o);\n\n\tinput [31:0] x, y, z;\n\toutput [31:0] o;\n\n\tassign o = z ^ (x & (y ^ z));\n\nendmodule\n\n\nmodule maj (x, y, z, o);\n\n\tinput [31:0] x, y, z;\n\toutput [31:0] o;\n\n\tassign o = (x & y) | (z & (x | y));\n\nendmodule\n\n\nmodule s0 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y[31:29] = x[6:4] ^ x[17:15];\n\tassign y[28:0] = {x[3:0], x[31:7]} ^ {x[14:0],x[31:18]} ^ x[31:3];\n\nendmodule\n\n\nmodule s1 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y[31:22] = x[16:7] ^ x[18:9];\n\tassign y[21:0] = {x[6:0],x[31:17]} ^ {x[8:0],x[31:19]} ^ x[31:10];\n\nendmodule\n\n\n"
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/sha256_transform.v",
    "content": "/*\n*\n* Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n*\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n\n`timescale 1ns/1ps\n\n// A quick define to help index 32-bit words inside a larger register.\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\n// Perform a SHA-256 transformation on the given 512-bit data, and 256-bit\n// initial state,\n// Outputs one 256-bit hash every LOOP cycle(s).\n//\n// The LOOP parameter determines both the size and speed of this module.\n// A value of 1 implies a fully unrolled SHA-256 calculation spanning 64 round\n// modules and calculating a full SHA-256 hash every clock cycle. A value of\n// 2 implies a half-unrolled loop, with 32 round modules and calculating\n// a full hash in 2 clock cycles. And so forth.\n\nmodule sha256_transform #(\n\tparameter LOOP = 7'd64\t\t// For ltcminer\n) (\n\tinput clk,\n\tinput feedback,\n\tinput [5:0] cnt,\n\tinput [255:0] rx_state,\n\tinput [511:0] rx_input,\n\toutput reg [255:0] tx_hash\n);\n\n\t// Constants defined by the SHA-2 standard.\n\tlocalparam Ks = {\n\t\t32'h428a2f98, 32'h71374491, 32'hb5c0fbcf, 32'he9b5dba5,\n\t\t32'h3956c25b, 32'h59f111f1, 32'h923f82a4, 32'hab1c5ed5,\n\t\t32'hd807aa98, 32'h12835b01, 32'h243185be, 32'h550c7dc3,\n\t\t32'h72be5d74, 32'h80deb1fe, 32'h9bdc06a7, 32'hc19bf174,\n\t\t32'he49b69c1, 32'hefbe4786, 32'h0fc19dc6, 32'h240ca1cc,\n\t\t32'h2de92c6f, 32'h4a7484aa, 32'h5cb0a9dc, 32'h76f988da,\n\t\t32'h983e5152, 32'ha831c66d, 32'hb00327c8, 32'hbf597fc7,\n\t\t32'hc6e00bf3, 32'hd5a79147, 32'h06ca6351, 32'h14292967,\n\t\t32'h27b70a85, 32'h2e1b2138, 32'h4d2c6dfc, 32'h53380d13,\n\t\t32'h650a7354, 32'h766a0abb, 32'h81c2c92e, 32'h92722c85,\n\t\t32'ha2bfe8a1, 32'ha81a664b, 32'hc24b8b70, 32'hc76c51a3,\n\t\t32'hd192e819, 32'hd6990624, 32'hf40e3585, 32'h106aa070,\n\t\t32'h19a4c116, 32'h1e376c08, 32'h2748774c, 32'h34b0bcb5,\n\t\t32'h391c0cb3, 32'h4ed8aa4a, 32'h5b9cca4f, 32'h682e6ff3,\n\t\t32'h748f82ee, 32'h78a5636f, 32'h84c87814, 32'h8cc70208,\n\t\t32'h90befffa, 32'ha4506ceb, 32'hbef9a3f7, 32'hc67178f2};\n\n\n\tgenvar i;\n\n\tgenerate\n\n\t\tfor (i = 0; i < 64/LOOP; i = i + 1) begin : HASHERS\n\t\t\t// These are declared as registers in sha256_digester\n\t\t\twire [511:0] W;\t\t\t// reg tx_w\n\t\t\twire [255:0] state;\t\t// reg tx_state\n\n\t\t\tif(i == 0)\n\t\t\t\tsha256_digester U (\n\t\t\t\t\t.clk(clk),\n\t\t\t\t\t.k(Ks[32*(63-cnt) +: 32]),\n\t\t\t\t\t.rx_w(feedback ? W : rx_input),\n\t\t\t\t\t.rx_state(feedback ? state : rx_state),\n\t\t\t\t\t.tx_w(W),\n\t\t\t\t\t.tx_state(state)\n\t\t\t\t);\n\t\t\telse\n\t\t\t\tsha256_digester U (\n\t\t\t\t\t.clk(clk),\n\t\t\t\t\t.k(Ks[32*(63-LOOP*i-cnt) +: 32]),\n\t\t\t\t\t.rx_w(feedback ? W : HASHERS[i-1].W),\n\t\t\t\t\t.rx_state(feedback ? state : HASHERS[i-1].state),\n\t\t\t\t\t.tx_w(W),\n\t\t\t\t\t.tx_state(state)\n\t\t\t\t);\n\t\tend\n\n\tendgenerate\n\n\talways @ (posedge clk)\n\tbegin\n\t\tif (!feedback)\n\t\tbegin\n\t\t\ttx_hash[`IDX(0)] <= rx_state[`IDX(0)] + HASHERS[64/LOOP-6'd1].state[`IDX(0)];\n\t\t\ttx_hash[`IDX(1)] <= rx_state[`IDX(1)] + HASHERS[64/LOOP-6'd1].state[`IDX(1)];\n\t\t\ttx_hash[`IDX(2)] <= rx_state[`IDX(2)] + HASHERS[64/LOOP-6'd1].state[`IDX(2)];\n\t\t\ttx_hash[`IDX(3)] <= rx_state[`IDX(3)] + HASHERS[64/LOOP-6'd1].state[`IDX(3)];\n\t\t\ttx_hash[`IDX(4)] <= rx_state[`IDX(4)] + HASHERS[64/LOOP-6'd1].state[`IDX(4)];\n\t\t\ttx_hash[`IDX(5)] <= rx_state[`IDX(5)] + HASHERS[64/LOOP-6'd1].state[`IDX(5)];\n\t\t\ttx_hash[`IDX(6)] <= rx_state[`IDX(6)] + HASHERS[64/LOOP-6'd1].state[`IDX(6)];\n\t\t\ttx_hash[`IDX(7)] <= rx_state[`IDX(7)] + HASHERS[64/LOOP-6'd1].state[`IDX(7)];\n\t\tend\n\tend\n\n\nendmodule\n\n\nmodule sha256_digester (clk, k, rx_w, rx_state, tx_w, tx_state);\n\n\tinput clk;\n\tinput [31:0] k;\n\tinput [511:0] rx_w;\n\tinput [255:0] rx_state;\n\n\toutput reg [511:0] tx_w;\n\toutput reg [255:0] tx_state;\n\n\n\twire [31:0] e0_w, e1_w, ch_w, maj_w, s0_w, s1_w;\n\n\n\te0\te0_blk\t(rx_state[`IDX(0)], e0_w);\n\te1\te1_blk\t(rx_state[`IDX(4)], e1_w);\n\tch\tch_blk\t(rx_state[`IDX(4)], rx_state[`IDX(5)], rx_state[`IDX(6)], ch_w);\n\tmaj\tmaj_blk\t(rx_state[`IDX(0)], rx_state[`IDX(1)], rx_state[`IDX(2)], maj_w);\n\ts0\ts0_blk\t(rx_w[63:32], s0_w);\n\ts1\ts1_blk\t(rx_w[479:448], s1_w);\n\n\twire [31:0] t1 = rx_state[`IDX(7)] + e1_w + ch_w + rx_w[31:0] + k;\n\twire [31:0] t2 = e0_w + maj_w;\n\twire [31:0] new_w = s1_w + rx_w[319:288] + s0_w + rx_w[31:0];\n\t\n\n\talways @ (posedge clk)\n\tbegin\n\t\ttx_w[511:480] <= new_w;\n\t\ttx_w[479:0] <= rx_w[511:32];\n\n\t\ttx_state[`IDX(7)] <= rx_state[`IDX(6)];\n\t\ttx_state[`IDX(6)] <= rx_state[`IDX(5)];\n\t\ttx_state[`IDX(5)] <= rx_state[`IDX(4)];\n\t\ttx_state[`IDX(4)] <= rx_state[`IDX(3)] + t1;\n\t\ttx_state[`IDX(3)] <= rx_state[`IDX(2)];\n\t\ttx_state[`IDX(2)] <= rx_state[`IDX(1)];\n\t\ttx_state[`IDX(1)] <= rx_state[`IDX(0)];\n\t\ttx_state[`IDX(0)] <= t1 + t2;\n\tend\n\nendmodule\n"
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/sim_ram.v",
    "content": "// sim_ram.v - identical to xilinx_ram.v (use for altera simulation to avoid\n// the need to specify library path for the altsyncram)\n\nmodule ram # ( parameter ADDRBITS=10 ) (\n\traddr,\n\twaddr,\n\tclock,\n\tdata,\n\twren,\n\tq);\n\n\tinput\t[ADDRBITS-1:0]  raddr;\n\tinput\t[ADDRBITS-1:0]  waddr;\n\tinput\t  clock;\n\tinput\t[255:0]  data;\n\tinput\t  wren;\n\toutput\t[255:0]  q;\n\n\treg [255:0] store [(2 << (ADDRBITS-1))-1:0];\n\treg[ADDRBITS-1:0] raddr_reg;\n\t\n\talways @ (posedge clock)\n\tbegin\n\t\traddr_reg <= raddr;\n\t\tif (wren)\n\t\t\tstore[waddr] <= data;\n\tend\n\t\n\tassign q = store[raddr_reg];\n\t\t\t\nendmodule"
  },
  {
    "path": "experimental/DE2-115-SLOWSIXTEEN/test_ltcminer.v",
    "content": "// Testbench for ltcminer.v\n\n`timescale 1ns/1ps\n\nmodule test_ltcminer ();\n\n\treg clk = 1'b0;\n\t\n\t wire [7:0] LEDS_out;\n\tltcminer uut (clk, LEDS_out);\n\t//ltcminer uut (clk);\n\n\treg [31:0] cycle = 32'd0;\n\n\tinitial begin\n\t\tclk = 0;\n\t\t\n\t\twhile(1)\n\t\tbegin\n\t\t\t#5 clk = 1; #5 clk = 0;\n\t\tend\n\tend\n\n\talways @ (posedge clk)\n\tbegin\n\t\tcycle <= cycle + 32'd1;\n\tend\n\nendmodule\n\n"
  },
  {
    "path": "experimental/LX150-EIGHT-A/README.txt",
    "content": "LX150-EIGHT-A\n\nEight threads running through a fully pipelined salsa (though we still roll it\nfour times and repeat for the block mix). Automatically sets the LOOKAHEAD_GAP\nto 2,4, or 8 depending on the number of cores selected.\n\nThis needs to run at > 100MHz to match the original 25MHz unpipelined code\nhowever its currently limited to 75MHz or thereabouts, so performance is poor.\nWith some work on fanout (the RAM address is particularily slow and may need\nan additional pipeline stage) and a separate clock for the pbkdfengine, it could\nperhaps go significantly faster. This will be tried in LX150-EIGHT-B since the\nseparate clocking scheme is a major change.\n\nThe code is still rather buggy. There is a 10% loss of shares which is possibly\ndown to the periodic reset on loadnonce, which is required to keep the pipeline\nin sync as thread execution time is variable."
  },
  {
    "path": "experimental/LX150-EIGHT-A/ltcminer_icarus.ucf",
    "content": "# Based on https://github.com/ngzhang/Icarus/blob/master/FPGA_project/Src/fpgaminer_top.ucf\n\nNET \"hash_clk\" TNM_NET = \"hash_clk\";\nNET \"uart_clk\" TNM_NET = \"uart_clk\";\n\n# 40MHz hash_clk\nTIMESPEC TS_hash_clk = PERIOD \"hash_clk\" 40 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\n# 12.5MHz uart_clk\nTIMESPEC TS_uart_clk = PERIOD \"uart_clk\" 80 ns HIGH 50 %;\n\nNET \"osc_clk\" LOC = J1 | IOSTANDARD = LVCMOS33;\n\n# serial port receive & transmit\nNET \"RxD\" LOC = D1 | IOSTANDARD = LVCMOS33;\nNET \"TxD\" LOC = B1 | IOSTANDARD = LVCMOS33;\n\n# TTL level serial port: ja3 = rxd, ja2 = txd\nNET \"extminer_txd[0]\" LOC = D22 | IOSTANDARD = LVCMOS33;\nNET \"extminer_rxd[0]\" LOC = B22 | IOSTANDARD = LVCMOS33;\n\nNET \"led[0]\" LOC = A18 | IOSTANDARD = LVCMOS33;\nNET \"led[1]\" LOC = B18 | IOSTANDARD = LVCMOS33;\nNET \"led[2]\" LOC = A17 | IOSTANDARD = LVCMOS33;\nNET \"led[3]\" LOC = A16 | IOSTANDARD = LVCMOS33;\n\nNET \"dip[0]\" LOC = A4 | IOSTANDARD = LVCMOS33;\nNET \"dip[1]\" LOC = D6 | IOSTANDARD = LVCMOS33;\nNET \"dip[2]\" LOC = C6 | IOSTANDARD = LVCMOS33;\nNET \"dip[3]\" LOC = C8 | IOSTANDARD = LVCMOS33;\n\nNET \"TMP_SCL\" LOC = C1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_SDA\" LOC = E1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_ALERT\" LOC = C3 | IOSTANDARD = LVCMOS33 | PULLUP;\n"
  },
  {
    "path": "experimental/LX150-EIGHT-A/ltcminer_icarus.v",
    "content": "/* ltcminer_icarus.v copyright kramble 2013\n * Based on https://github.com/teknohog/Open-Source-FPGA-Bitcoin-Miner/tree/master/projects/Xilinx_cluster_cgminer\n * Hub code for a cluster of miners using async links\n * by teknohog\n */\n\n`include \"../../source/sha-256-functions.v\"\n`include \"../../source/sha256_transform.v\"\n`include \"../../ICARUS-LX150/xilinx_pll.v\"\n`include \"../../ICARUS-LX150/uart_receiver.v\"\n`include \"../../ICARUS-LX150/uart_transmitter.v\"\n`include \"../../ICARUS-LX150/serial.v\"\n`include \"../../ICARUS-LX150/serial_hub.v\"\n`include \"../../ICARUS-LX150/hub_core.v\"\n`include \"../../ICARUS-LX150/pwm_fade.v\"\n\nmodule ltcminer_icarus (osc_clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n// NB SPEED_MHZ resolution is 5MHz steps to keep pll divide ratio sensible. Change the divider in xilinx_pll.v if you\n// want other steps (1MHz is not sensible as it requires divide 100 which is not in the allowed range 1..32 for DCM_SP)\n// TODO dynamic speed adjustment (possibly use top byte of target to set multiplier, this keeps serial interface compatible)\n\n`ifdef SPEED_MHZ\n\tparameter SPEED_MHZ = `SPEED_MHZ;\n`else\n\tparameter SPEED_MHZ = 50;\n`endif\n\n`ifdef SERIAL_CLK\n\tparameter comm_clk_frequency = `SERIAL_CLK;\n`else\n\tparameter comm_clk_frequency = 12_500_000;\t\t// 100MHz divide 8\n`endif\n\n`ifdef BAUD_RATE\n\tparameter BAUD_RATE = `BAUD_RATE;\n`else\n\tparameter BAUD_RATE = 115_200;\n`endif\n\n// kramble - nonce distribution is crude using top 4 bits of nonce so max LOCAL_MINERS = 8\n// teknohog's was more sophisticated, but requires modification of hashcore.v\n\n// Miners on the same FPGA with this hub\n`ifdef LOCAL_MINERS\n\tparameter LOCAL_MINERS = `LOCAL_MINERS;\n`else\n\tparameter LOCAL_MINERS = 2;\t\t\t\t\t\t// One to four cores (configures ADDRBITS automatically)\n`endif\n\n`ifdef ADDRBITS\n\tparameter ADDRBITS = `ADDRBITS;\n`else\n\tparameter ADDRBITS = 12 - clog2(LOCAL_MINERS);\t// May want to override for simulation\n`endif\n\n// kramble - nonce distribution only works for a single external port \n`ifdef EXT_PORTS\n\tparameter EXT_PORTS = `EXT_PORTS;\n`else\n\tparameter EXT_PORTS = 1;\n`endif\n\n\tlocalparam SLAVES = LOCAL_MINERS + EXT_PORTS;\n\n// kramble - since using separare clocks for uart and hasher, need clock crossing logic\n\tinput osc_clk;\n\twire hash_clk, uart_clk;\n\n`ifndef SIM\n\tmain_pll # (.SPEED_MHZ(SPEED_MHZ)) pll_blk (.CLKIN_IN(osc_clk), .CLKFX_OUT(hash_clk), .CLKDV_OUT(uart_clk));\n`else\n\tassign hash_clk = osc_clk;\n\tassign uart_clk = osc_clk;\n`endif\n   \n\tinput TMP_SCL, TMP_SDA, TMP_ALERT;\t// Unused but set to PULLUP so as to avoid turning on the HOT LED\n\t\t\t\t\t\t\t\t\t\t// TODO implement I2C protocol to talk to temperature sensor chip (TMP101?)\n\t\t\t\t\t\t\t\t\t\t// and drive FAN speed control output.\n\n\tinput [3:0]dip;\n\twire reset, nonce_chip;\n\tassign reset = dip[0];\t\t\t// Not used\n\tassign nonce_chip = dip[1];\t\t// Distinguishes between the two Icarus FPGA's\n\n\t// Work distribution is simply copying to all miners, so no logic\n\t// needed there, simply copy the RxD.\n\tinput\tRxD;\n\toutput\tTxD;\n\n\t// Results from the input buffers (in serial_hub.v) of each slave\n\twire [SLAVES*32-1:0]\tslave_nonces;\n\twire [SLAVES-1:0]\t\tnew_nonces;\n\n\t// Using the same transmission code as individual miners from serial.v\n\twire\t\tserial_send;\n\twire\t\tserial_busy;\n\twire [31:0]\tgolden_nonce;\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) sertx (.clk(uart_clk), .TxD(TxD), .send(serial_send), .busy(serial_busy), .word(golden_nonce));\n\n\thub_core #(.SLAVES(SLAVES)) hc (.uart_clk(uart_clk), .new_nonces(new_nonces), .golden_nonce(golden_nonce), .serial_send(serial_send), .serial_busy(serial_busy), .slave_nonces(slave_nonces));\n\n\t// Common workdata input for local miners\n\twire [255:0]\tdata1, data2;\n\twire [127:0]\tdata3;\n\twire [31:0]\t\ttarget;\n\t// reg [31:0]\ttargetreg = 32'hffffffff;\t// TEST - matches ANYTHING\n\treg  [31:0]\t\ttargetreg = 32'h000007ff;\t// Start at sane value (overwritten by serial_receive)\n\twire\t\t\trx_done;\t\t// Signals hashcore to reset the nonce\n\t\t\t\t\t\t\t\t\t// NB in my implementation, it loads the nonce from data3 which should be fine as\n\t\t\t\t\t\t\t\t\t// this should be zero, but also supports testing using non-zero nonces.\n\n\t// Synchronise across clock domains from uart_clk to hash_clk\n\t// This probably looks amateurish (mea maxima culpa, novice verilogger at work), but should be OK\n\treg rx_done_toggle = 1'b0;\t\t// uart_clk domain\n\talways @ (posedge uart_clk)\n\t\trx_done_toggle <= rx_done_toggle ^ rx_done;\n\n\treg rx_done_toggle_d1 = 1'b0;\t// hash_clk domain\n\treg rx_done_toggle_d2 = 1'b0;\n\treg rx_done_toggle_d3 = 1'b0;\n\t\n\twire loadnonce;\n\tassign loadnonce = rx_done_toggle_d3 ^ rx_done_toggle_d2;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\trx_done_toggle_d1 <= rx_done_toggle;\n\t\trx_done_toggle_d2 <= rx_done_toggle_d1;\n\t\trx_done_toggle_d3 <= rx_done_toggle_d2;\n\t\tif (loadnonce)\n\t\t\ttargetreg <= target;\n\tend\n\t// End of clock domain sync\n\n\tserial_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) serrx (.clk(uart_clk), .RxD(RxD), .data1(data1),\n\t\t\t\t\t\t.data2(data2), .data3(data3), .target(target), .rx_done(rx_done));\n\n\t// Local miners now directly connected\n\tgenerate\n\t\tgenvar i;\n\t\tfor (i = 0; i < LOCAL_MINERS; i = i + 1)\n\t\t// begin: for_local_miners ... too verbose, so...\n\t\tbegin: miners\n\t\t\twire [31:0] nonce_out;\t// Not used\n\t\t\twire [2:0] nonce_core = i;\n\t\t\twire gn_match;\n\t\t\t\n\t\t\twire salsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift;\n\n\t\t\t// Currently one pbkdfengine per salsaengine - TODO share the pbkdfengine for several salsaengines\n\t\t\tpbkdfengine P (.hash_clk(hash_clk), .data1(data1), .data2(data2), .data3(data3), .target(targetreg),\n\t\t\t\t.nonce_msb({nonce_chip, nonce_core}), .nonce_out(nonce_out), .golden_nonce_out(slave_nonces[i*32+31:i*32]),\n\t\t\t\t.golden_nonce_match(gn_match), .loadnonce(loadnonce),\n\t\t\t\t.salsa_din(salsa_din), .salsa_dout(salsa_dout), .salsa_busy(salsa_busy), .salsa_result(salsa_result),\n\t\t\t\t.salsa_reset(salsa_reset), .salsa_start(salsa_start), .salsa_shift(salsa_shift));\n\n\t\t\tsalsaengine #(.ADDRBITS(ADDRBITS)) S (.hash_clk(hash_clk), .reset(salsa_reset), .din(salsa_din), .dout(salsa_dout),\n\t\t\t\t.shift(salsa_shift), .start(salsa_start), .busy(salsa_busy), .result(salsa_result) );\n\t\t\t\t\t\n\t\t\t// Synchronise across clock domains from hash_clk to uart_clk for: assign new_nonces[i] = gn_match;\n\t\t\treg gn_match_toggle = 1'b0;\t\t// hash_clk domain\n\t\t\talways @ (posedge hash_clk)\n\t\t\t\tgn_match_toggle <= gn_match_toggle ^ gn_match;\n\n\t\t\treg gn_match_toggle_d1 = 1'b0;\t// uart_clk domain\n\t\t\treg gn_match_toggle_d2 = 1'b0;\n\t\t\treg gn_match_toggle_d3 = 1'b0;\n\n\t\t\tassign new_nonces[i] = gn_match_toggle_d3 ^ gn_match_toggle_d2;\n\n\t\t\talways @ (posedge uart_clk)\n\t\t\tbegin\n\t\t\t\tgn_match_toggle_d1 <= gn_match_toggle;\n\t\t\t\tgn_match_toggle_d2 <= gn_match_toggle_d1;\n\t\t\t\tgn_match_toggle_d3 <= gn_match_toggle_d2;\n\t\t\tend\n\t\t\t// End of clock domain sync\n\t\tend // for\n\tendgenerate\n\n\t// External miner ports, results appended to the same\n\t// slave_nonces/new_nonces as local ones\n\toutput [EXT_PORTS-1:0] extminer_txd;\n\tinput [EXT_PORTS-1:0]  extminer_rxd;\n\tassign extminer_txd = {EXT_PORTS{RxD}};\n\n\tgenerate\n\t\tgenvar j;\n\t\tfor (j = LOCAL_MINERS; j < SLAVES; j = j + 1)\n\t\t// begin: for_ports ... too verbose, so ...\n\t\tbegin: ports\n\t\t\tslave_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) slrx (.clk(uart_clk), .RxD(extminer_rxd[j-LOCAL_MINERS]), .nonce(slave_nonces[j*32+31:j*32]), .new_nonce(new_nonces[j]));\n\t\tend\n\tendgenerate\n\n\toutput [3:0] led;\n\tassign led[1] = ~RxD;\n\tassign led[2] = ~TxD;\n\tassign led[3] = ~ (TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED - held low (the TMP pins are PULLUP, this is a fudge to\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// avoid warning about unused inputs)\n\n\t// Light up only from locally found nonces, not ext_port results\n\tpwm_fade pf (.clk(uart_clk), .trigger(|new_nonces[LOCAL_MINERS-1:0]), .drive(led[0]));\n   \nendmodule\n"
  },
  {
    "path": "experimental/LX150-EIGHT-A/pbkdfengine.v",
    "content": "/* pbkdfengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`define ICARUS\t\t\t// Comment this out when using the altera virtual_wire interface in ltcminer.v\n\t\n`timescale 1ns/1ps\n\nmodule pbkdfengine\n\t(hash_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce,\n\t\t\tsalsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift);\n\n\tinput hash_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\n\toutput [31:0] nonce_out;\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\n\tinput salsa_dout;\n\toutput salsa_din;\n\tinput salsa_busy, salsa_result;\n\toutput salsa_reset;\n\toutput salsa_start;\n\toutput reg salsa_shift = 1'b0;\n\n\treg [3:0]resetcycles = 0;\n\treg reset = 1'b0;\n\tassign salsa_reset = reset;\t\t// Propagate reset to salsaengine\n\n`ifdef WANTCYCLICRESET\t\t\n\treg [23:0]cycresetcount = 0;\n`endif\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\t// Hard code a 15 cycle reset (NB assumes THREADS=8 in salsaengine, else we need more)\n\t\tresetcycles <= resetcycles + 1;\n\t\tif (resetcycles == 0)\n\t\t\treset <= 1'b1;\n\t\tif (resetcycles == 15)\n\t\tbegin\n\t\t\treset <= 1'b0;\n\t\t\tresetcycles <= 15;\n\t\tend\n`ifdef WANTCYCLICRESET\t\t\n\t\t// Cyclical reset every 2_500_000 clocks to ensure salsa pipeline does not drift out of sync\n\t\t// This may be unneccessary if we reset every loadnonce\n\t\t// Actually it seems to do more harm than good, so disabled\n\t\tcycresetcount <= cycresetcount + 1;\n\t\tif (cycresetcount == 2_500_000)\t// 10 per second at 25MHz (adjust as neccessary)\n\t\tbegin\n\t\t\tcycresetcount <= 0;\n\t\t\tresetcycles <= 0;\n\t\tend\n`endif\t\t\n\t\t// Reset on loadnonce (the hash results will be junk anyway since data changes, so no loss of shares)\n\t\tif (loadnonce)\n\t\t\tresetcycles <= 0;\n\tend\n\t\n\t`ifndef ICARUS\n\treg [31:0] nonce_previous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\t`endif\n\n\t`ifndef NOMULTICORE\n\t`ifdef SIM\n\t\treg [27:0] nonce_cnt = 28'h318f;\t// Start point for simulation\n\t`else\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t`endif\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\tassign nonce_out = nonce;\n\n\treg [31:0] nonce_sr = 32'd0;\t\t// Nonce is shifted to salsaengine for storage/retrieval\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [31:0] blockcnt = 32'd0;\t// Takes values 1..4 for block iteration (NB could hardwire top 29 bits)\n\treg [1023:0] Xbuf = 1024'd0;\t// Shared input/output buffer and shift register\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\tassign salsa_din = Xbuf[1023];\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\t\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(hash_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\n\t// reg Clr_SMixInRdy = 1'b0;\t// Fudge this for now...\n\treg salsa_busy_d1 = 1'b0;\n\twire Clr_SMixInRdy;\n\tassign Clr_SMixInRdy = SMixInRdy_state & salsa_busy & ~salsa_busy_d1;\t// Clear on transition to busy\n\t\n\t// reg Set_SMixOutRdy = 1'b0;\t// Fudge this for now...\n\treg salsa_result_d1 = 1'b0;\n\twire Set_SMixOutRdy;\n\tassign Set_SMixOutRdy = ~SMixOutRdy_state & salsa_result & ~salsa_result_d1;\n\t\n\treg Clr_SMixOutRdy = 1'b0;\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tsalsa_busy_d1 <= salsa_busy;\n\t\tsalsa_result_d1 <= salsa_result;\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\t\t\t\n\t\t// CARE there is a race with Set_SMixInRdy, Clr_SMixOutRdy which are set in the FSM\n\t\t// Probably need to assert reset for two cycles to ensure consistency (acutally 15)\n\t\tif (reset)\n\t\tbegin\t\t\t\t\t\t\t// Reset takes priority\n\t\t\tSMixInRdy_state <= 1'b0;\n\t\t\tSMixOutRdy_state <= 1'b0;\n\t\tend\n\tend\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\tassign salsa_start = SMixInRdy;\n\t\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz)\n\t\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_SHIFT_IN=22, S_SHIFT_OUT=41,\t\t\t\t\t\t\t// Direction relative to salsa unit\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\treg start_output = 0;\n\treg\t[10:0]shift_count = 0;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\n\t\t`ifdef ICARUS\n\t\tif (loadnonce)\t\t\t\t// Separate clock domains means comparison is unsafe\n\t\t`else\n\t\tif (loadnonce || (nonce_previous_load != data3[127:96]))\n\t\t`endif\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_previous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\t`ifndef ICARUS\n\t\t\tnonce_previous_load <= data3[127:96];\n\t\t\t`endif\n\t\tend\n\t\t\n\t\tif (reset == 1'b1)\n\t\tbegin\n\t\t\tstate <= S_IDLE;\n\t\t\tstart_output <= 1'b0;\n\t\t\tsalsa_shift <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tshift_count <= 0;\n\t\t\t\t\tif (SMixOutRdy & ~start_output)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tstate <= S_SHIFT_OUT;\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (start_output ||\t// Process output\n\t\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'b0;\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\t\tblockcnt <= 32'd1;\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_sr : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tblockcnt, nonce, data3[95:0] };\n\t\t\t\t\t\tblockcnt <= blockcnt + 1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\t\t\n\t\t\t\tS_B6: begin\t// Shift output into X buffer from MSB->LSB\n\t\t\t\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\t\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\t\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\t\t\t\tXbuf[1023:768] <= tx_hash;\n\n\t\t\t\t\t\tif (blockcnt == 5)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// nonce_1 <= nonce;\n\t\t\t\t\t\t\t// nonce_2 <= nonce_1;\n\t\t\t\t\t\t\tnonce_sr <= nonce;\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 28'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 32'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\t\tstate <= S_SHIFT_IN;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\tblockcnt, nonce, data3[95:0] };\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_SHIFT_IN: begin\t\t\t\t\t\t\t// Shifting from PBKDF2_SHA256 to salsa\n\t\t\t\t\t\tsalsa_shift <= 1;\n\t\t\t\t\t\tif (salsa_shift)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXbuf <= { Xbuf[1022:0], nonce_sr[31] };\n\t\t\t\t\t\t\tnonce_sr <= { nonce_sr[30:0], salsa_dout };\n\t\t\t\t\t\tend\n\t\t\t\t\t\tshift_count <= shift_count + 1;\n\t\t\t\t\t\tif (shift_count == 1024+32)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tSet_SMixInRdy <= 1;\t\t\t// Flag salsa to start\n\t\t\t\t\t\t\tsalsa_shift <= 0;\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_SHIFT_OUT: begin\t\t\t\t\t\t\t// Shifting from salsa to PBKDF2_SHA256\n\t\t\t\t\t\t// nonce_2 <= nonce_1;\t\t\t\t// Already done this in S_B6 (MAY need nonce_3 though)\n\t\t\t\t\t\tsalsa_shift <= 1;\n\t\t\t\t\t\tif (salsa_shift)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXbuf <= { Xbuf[1022:0], nonce_sr[31] };\n\t\t\t\t\t\t\tnonce_sr <= { nonce_sr[30:0], salsa_dout };\n\t\t\t\t\t\tend\n\t\t\t\t\t\tshift_count <= shift_count + 1;\n\t\t\t\t\t\tif (shift_count == 1024+32)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1;\t\t\t// Flag self to start\n\t\t\t\t\t\t\tsalsa_shift <= 0;\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_sr;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n\tend\n\n\t// MixOut is little-endian word format to match scrypt.c so convert back to big-endian\n\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] mix;\n\t\tassign mix = Xbuf[`IDX(i)];\t\t// NB MixOut now shares Xbuf since shifted in/out\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\nendmodule"
  },
  {
    "path": "experimental/LX150-EIGHT-A/salsa_piped.v",
    "content": "/* salsa_piped.v ... fully registered salsa core (column and row results regs)\n*\n* Copyright (c) 2013 kramble\n* Derived from scrypt.c Copyright 2009 Colin Percival, 2011 ArtForz\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\nmodule salsa (clk, feedback, B, Bx, Bo, X0out, X1out, Xaddr);\n\n// Latency 9 clock cycles (4 col steps + 4 row + 1 sync), hence 4 salsa iterations in 36 cycles\n\ninput clk;\ninput feedback;\ninput [511:0]B;\ninput [511:0]Bx;\noutput [511:0]Bo;\noutput [511:0]X0out;\t// Pipelined B\noutput [511:0]X1out;\t// Pipelined Bx\noutput [9:0]Xaddr;\t\t// Address\n\nwire [511:0]xx;\t\t\t// Initial xor\nwire [511:0]xxd8;\t\t// Delayed 8 cycles\n\nwire [511:0]xr;\t\t\t// Output of salsa core\nreg [511:0]xrd;\t\t\t// Feedback (9th latency step to maintain sync with ram access)\n\nwire [9:0]addr;\t\t\t// Address from salsa\nreg [9:0]xxd7_addr;\n\n// X0/X1 delays ... just to check timing, probably need to use a ram location to reduce routing congestion\n\nreg [511:0]x0d1;\nreg [511:0]x0d2;\nreg [511:0]x0d3;\nreg [511:0]x0d4;\nreg [511:0]x0d5;\nreg [511:0]x0d6;\nreg [511:0]x0d7;\nreg [511:0]x0d8;\n\nreg [511:0]x1d1;\nreg [511:0]x1d2;\nreg [511:0]x1d3;\nreg [511:0]x1d4;\nreg [511:0]x1d5;\nreg [511:0]x1d6;\nreg [511:0]x1d7;\nreg [511:0]x1d8;\n\nassign X0out = x0d8;\nassign X1out = x1d8;\n\nsalsa_core salsa1 (clk, feedback ? xrd : xx, xr, addr);\n\nalways @ (posedge clk)\nbegin\n\txrd <= xr;\n\n\tx0d1 <= B;\n\tx0d2 <= x0d1;\n\tx0d3 <= x0d2;\n\tx0d4 <= x0d3;\n\tx0d5 <= x0d4;\n\tx0d6 <= x0d5;\n\tx0d7 <= x0d6;\n\tx0d8 <= x0d7;\n\t\n\tx1d1 <= Bx;\n\tx1d2 <= x1d1;\n\tx1d3 <= x1d2;\n\tx1d4 <= x1d3;\n\tx1d5 <= x1d4;\n\tx1d6 <= x1d5;\n\tx1d7 <= x1d6;\n\tx1d8 <= x1d7;\n\t\n\txxd7_addr <= x0d6[9:0] ^ x1d6[9:0];\nend\n\t\ngenvar i;\ngenerate\n\tfor (i = 0; i < 16; i = i + 1) begin : XX\n\t\t// Initial XOR. NB this adds to the propagation delay of the first salsa, may want register it.\n\t\tassign xx[`IDX(i)] = B[`IDX(i)] ^ Bx[`IDX(i)];\n\t\tassign xxd8[`IDX(i)] = x0d8[`IDX(i)] ^ x1d8[`IDX(i)];\t\t// Could do one cycle early (in reg) to save an xor delay\n\t\t// Final sum. NB Ouptut is at 8 cycle latency.\n\t\tassign Bo[`IDX(i)] = xxd8[`IDX(i)] + xr[`IDX(i)];\n\tend\nendgenerate\n\nassign Xaddr = xxd7_addr + addr;\n\nendmodule\n\nmodule salsa_core (clk, x, out, addr);\n\ninput clk;\ninput [511:0]x;\noutput [511:0]out;\noutput [9:0]addr;\n\n// This is clunky due to my lack of verilog skills but it works so elegance can come later\n// ... actually its now gotten quite ridiculous, see KLUDGE below\n\n// Aliases for inputs\n\nwire [31:0] x00;\nwire [31:0] x01;\nwire [31:0] x02;\nwire [31:0] x03;\nwire [31:0] x04;\nwire [31:0] x05;\nwire [31:0] x06;\nwire [31:0] x07;\nwire [31:0] x08;\nwire [31:0] x09;\nwire [31:0] x10;\nwire [31:0] x11;\nwire [31:0] x12;\nwire [31:0] x13;\nwire [31:0] x14;\nwire [31:0] x15;\n\nassign x00 = x[`IDX(0)];\nassign x01 = x[`IDX(1)];\nassign x02 = x[`IDX(2)];\nassign x03 = x[`IDX(3)];\nassign x04 = x[`IDX(4)];\nassign x05 = x[`IDX(5)];\nassign x06 = x[`IDX(6)];\nassign x07 = x[`IDX(7)];\nassign x08 = x[`IDX(8)];\nassign x09 = x[`IDX(9)];\nassign x10 = x[`IDX(10)];\nassign x11 = x[`IDX(11)];\nassign x12 = x[`IDX(12)];\nassign x13 = x[`IDX(13)];\nassign x14 = x[`IDX(14)];\nassign x15 = x[`IDX(15)];\n\n// Column & Row Results (yup, I wrote a program to generate these) ...\n// Not all of these are used, but let the synthesizer take care of that for now\n// TODO prune the unused ones, may be important with certain synth settings\n\n// BEGIN KLUDGE\n`include \"sgen.inc\"\t\t\t// .inc so it does not accidentally get compiled separately as .v\n// END KLUDGE\n\nwire [31:0]c00s;\t\t\t// Column sums\nwire [31:0]c01s;\nwire [31:0]c02s;\nwire [31:0]c03s;\nwire [31:0]c04s;\nwire [31:0]c05s;\nwire [31:0]c06s;\nwire [31:0]c07s;\nwire [31:0]c08s;\nwire [31:0]c09s;\nwire [31:0]c10s;\nwire [31:0]c11s;\nwire [31:0]c12s;\nwire [31:0]c13s;\nwire [31:0]c14s;\nwire [31:0]c15s;\n\nwire [31:0]r00s;\t\t\t// Row sums\nwire [31:0]r01s;\nwire [31:0]r02s;\nwire [31:0]r03s;\nwire [31:0]r04s;\nwire [31:0]r05s;\nwire [31:0]r06s;\nwire [31:0]r07s;\nwire [31:0]r08s;\nwire [31:0]r09s;\nwire [31:0]r10s;\nwire [31:0]r11s;\nwire [31:0]r12s;\nwire [31:0]r13s;\nwire [31:0]r14s;\nwire [31:0]r15s;\n\nwire [31:0]r00sx;\n\n/* From scrypt.c\n\n#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))\n\tfor (i = 0; i < 8; i += 2) {\n\t\t// Operate on columns\n\t\tx04 ^= R(x00+x12, 7);\tx09 ^= R(x05+x01, 7);\tx14 ^= R(x10+x06, 7);\tx03 ^= R(x15+x11, 7);\n\t\tx08 ^= R(x04+x00, 9);\tx13 ^= R(x09+x05, 9);\tx02 ^= R(x14+x10, 9);\tx07 ^= R(x03+x15, 9);\n\t\tx12 ^= R(x08+x04,13);\tx01 ^= R(x13+x09,13);\tx06 ^= R(x02+x14,13);\tx11 ^= R(x07+x03,13);\n\t\tx00 ^= R(x12+x08,18);\tx05 ^= R(x01+x13,18);\tx10 ^= R(x06+x02,18);\tx15 ^= R(x11+x07,18);\n\n\t\t// Operate on rows\n\t\tx01 ^= R(x00+x03, 7);\tx06 ^= R(x05+x04, 7);\tx11 ^= R(x10+x09, 7);\tx12 ^= R(x15+x14, 7);\n\t\tx02 ^= R(x01+x00, 9);\tx07 ^= R(x06+x05, 9);\tx08 ^= R(x11+x10, 9);\tx13 ^= R(x12+x15, 9);\n\t\tx03 ^= R(x02+x01,13);\tx04 ^= R(x07+x06,13);\tx09 ^= R(x08+x11,13);\tx14 ^= R(x13+x12,13);\n\t\tx00 ^= R(x03+x02,18);\tx05 ^= R(x04+x07,18);\tx10 ^= R(x09+x08,18);\tx15 ^= R(x14+x13,18);\n\t}\n*/\n\n// cols\n\nassign c04s = x00 + x12;\nassign c09s = x05 + x01;\nassign c14s = x10 + x06;\nassign c03s = x15 + x11;\n\nassign c08s = c04 + x00d1;\nassign c13s = c09 + x05d1;\nassign c02s = c14 + x10d1;\nassign c07s = c03 + x15d1;\n\nassign c12s = c08 + c04d1;\nassign c01s = c13 + c09d1;\nassign c06s = c02 + c14d1;\nassign c11s = c07 + c03d1;\n\nassign c00s = c12 + c08d1;\nassign c05s = c01 + c13d1;\nassign c10s = c06 + c02d1;\nassign c15s = c11 + c07d1;\n\n// rows\n\nassign r01s = c00 + c03d3;\nassign r06s = c05 + c04d3;\nassign r11s = c10 + c09d3;\nassign r12s = c15 + c14d3;\n\nassign r02s = r01 + c00d1;\nassign r07s = r06 + c05d1;\nassign r08s = r11 + c10d1;\nassign r13s = r12 + c15d1;\n\nassign r03s = r02 + r01d1;\nassign r04s = r07 + r06d1;\nassign r09s = r08 + r11d1;\nassign r14s = r13 + r12d1;\n\nassign r00s = r03 + r02d1;\nassign r05s = r04 + r07d1;\nassign r10s = r09 + r08d1;\nassign r15s = r14 + r13d1;\n\n// Hack to bring out address one cycle earlier\nassign r00sx = c00d3 ^ { r00s[13:0], r00s[31:14] };\nassign addr = r00sx[9:0];\n\nassign out = { r15, r14d1, r13d2, r12d3, r11d3, r10, r09d1, r08d2, r07d2, r06d3, r05, r04d1, r03d1, r02d2, r01d3, r00 };\n\nalways @ (posedge clk)\nbegin\n\tc04 <= x04 ^ { c04s[24:0], c04s[31:25] };\n\tc09 <= x09 ^ { c09s[24:0], c09s[31:25] };\n\tc14 <= x14 ^ { c14s[24:0], c14s[31:25] };\n\tc03 <= x03 ^ { c03s[24:0], c03s[31:25] };\n\n\tc08 <= x08d1 ^ { c08s[22:0], c08s[31:23] };\n\tc13 <= x13d1 ^ { c13s[22:0], c13s[31:23] };\n\tc02 <= x02d1 ^ { c02s[22:0], c02s[31:23] };\n\tc07 <= x07d1 ^ { c07s[22:0], c07s[31:23] };\n\n\tc12 <= x12d2 ^ { c12s[18:0], c12s[31:19] };\n\tc01 <= x01d2 ^ { c01s[18:0], c01s[31:19] };\n\tc06 <= x06d2 ^ { c06s[18:0], c06s[31:19] };\n\tc11 <= x11d2 ^ { c11s[18:0], c11s[31:19] };\n\n\tc00 <= x00d3 ^ { c00s[13:0], c00s[31:14] };\n\tc05 <= x05d3 ^ { c05s[13:0], c05s[31:14] };\n\tc10 <= x10d3 ^ { c10s[13:0], c10s[31:14] };\n\tc15 <= x15d3 ^ { c15s[13:0], c15s[31:14] };\n\n\tr01 <= c01d1 ^ { r01s[24:0], r01s[31:25] };\n\tr06 <= c06d1 ^ { r06s[24:0], r06s[31:25] };\n\tr11 <= c11d1 ^ { r11s[24:0], r11s[31:25] };\n\tr12 <= c12d1 ^ { r12s[24:0], r12s[31:25] };\n\n\tr02 <= c02d3 ^ { r02s[22:0], r02s[31:23] };\n\tr07 <= c07d3 ^ { r07s[22:0], r07s[31:23] };\n\tr08 <= c08d3 ^ { r08s[22:0], r08s[31:23] };\n\tr13 <= c13d3 ^ { r13s[22:0], r13s[31:23] };\n\n\tr03 <= c03d5 ^ { r03s[18:0], r03s[31:19] };\n\tr04 <= c04d5 ^ { r04s[18:0], r04s[31:19] };\n\tr09 <= c09d5 ^ { r09s[18:0], r09s[31:19] };\n\tr14 <= c14d5 ^ { r14s[18:0], r14s[31:19] };\n\n\t// r00 <= c00d3 ^ { r00s[13:0], r00s[31:14] };\n\tr00 <= r00sx;\n\tr05 <= c05d3 ^ { r05s[13:0], r05s[31:14] };\n\tr10 <= c10d3 ^ { r10s[13:0], r10s[31:14] };\n\tr15 <= c15d3 ^ { r15s[13:0], r15s[31:14] };\nend\nendmodule\n"
  },
  {
    "path": "experimental/LX150-EIGHT-A/salsaengine.v",
    "content": "/* salsaengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n// NB HALFRAM no longer applies, configure via parameters ADDRBITS, THREADS\n\n// Bracket this config option in SIM so we don't accidentally leave it set in a live build\n`ifdef SIM\n//`define ONETHREAD\t// Start one thread only (for SIMULATION less confusing and faster startup)\n`endif\n\n`timescale 1ns/1ps\n\nmodule salsaengine (hash_clk, reset, din, dout, shift, start, busy, result );\n\n\tinput hash_clk;\n\tinput reset;\t// NB Needs a long reset (at least THREADS+4) to initialize correctly, this is done in pbkdfengine (15 cycles)\n\tinput din;\n\tinput shift;\n\tinput start;\n\toutput busy;\n\toutput reg result = 1'b0;\n\toutput dout;\n\t\n\t// Configure ADDRBITS to allocate RAM for core (automatically sets LOOKAHEAD_GAP)\n\t// NB do not use ADDRBITS > 13 for THREADS=8 since this corresponds to more than a full scratchpad\n\n\t// These settings are now overriden in ltcminer_icarus.v determined by LOCAL_MINERS ...\n\t// parameter ADDRBITS = 13;\t// 8MBit RAM allocated to core, full scratchpad (will not fit LX150)\n\tparameter ADDRBITS = 12;\t// 4MBit RAM allocated to core, half scratchpad\n\t// parameter ADDRBITS = 11;\t// 2MBit RAM allocated to core, quarter scratchpad\n\t// parameter ADDRBITS = 10;\t// 1MBit RAM allocated to core, eighth scratchpad\n\n\t// Do not change THREADS - this must match the salsa pipeline (code is untested for other values)\n\tparameter THREADS = 8;\t\t// NB Phase has THREADS+1 cycles\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n\tparameter THREADS_BITS = clog2(THREADS);\n\t\n\t// Workaround for range-reversal error in inactive code when ADDRBITS=13\n\tparameter ADDRBITSX = (ADDRBITS == 13) ? ADDRBITS-1 : ADDRBITS;\n\n\treg [THREADS_BITS:0]phase = 0;\n\treg [THREADS_BITS:0]phase_d = THREADS;\n\n\talways @ (posedge hash_clk)\t\t// Phase control\n\tbegin\n\t\tphase <= (phase == THREADS) ? 0 : phase + 1;\n\t\tphase_d <= phase;\n\tend\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\tparameter XSnull = 0, XSload = 1, XSmix = 2, XSram = 4;\t\t\t// One-hot since these map directly to mux contrls\n\treg [2:0] XCtl = XSnull;\n\n\tparameter R_IDLE=0, R_START=1, R_WRITE=2, R_MIX=4, R_INT=8;\t\t// Try explicit one-hot [HMMM synthesyzer changes to this gray]\n\treg [3:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg [5:0] mcount = 5'd0;\t// Salsa latency\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs\n\treg mixfeedback = 1'b0;\n\treg mixfeedback_d = 1'b0;\t// Fudge\n\treg addrsourceMix = 1'b0;\n\treg addrsourceMix_d = 1'b0;\n\treg addrsourceSave = 1'b0;\n\treg mixspecial = 1'b0;\n\treg xoren = 1'b1;\n\treg [THREADS_BITS+1:0] intcycles = 0;\t// Number of interpolation cycles required ... How many do we need? Say THREADS_BITS+1\n\n\twire [511:0] Xmix;\n\treg [511:0] X0;\n\treg [511:0] X1;\n\twire [511:0] X0in;\n\twire [511:0] X1in;\n\twire [511:0] X0out;\n\twire [511:0] X1out;\n\treg [1023:0] salsaShiftReg;\n\treg [31:0] nonce_sr;\t\t\t// In series with salsaShiftReg\n\tassign dout = salsaShiftReg[1023];\n\n\treg [511:0] Xmix_d;\n\treg [511:0] X1out_d;\n\n\t// sstate is implemented in block ram\n\treg [THREADS_BITS+38:0] sstate [THREADS-1:0];\t\t// NB initialized via a long reset (see pbkdfengine)\n\twire [3:0] mstate_in;\n\twire [10:0] cycle_in;\n\twire [5:0] mcount_in;\n\twire [9:0] writeaddr_in;\n\twire doneROM_in;\n\twire mixfeedback_in;\n\twire addrsourceMix_in;\n\twire addrsourceSave_in;\n\twire mixspecial_in;\n\twire [THREADS_BITS+1:0] intcycles_in;\t\t\t\t// How many do we need? Say THREADS_BITS+1\n\n\treg [31:0] snonce [THREADS-1:0];\t\t\t\t\t// Nonce store. Note bidirectional loading below, this will either implement\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// as registers or dual-port ram, so do NOT integrate with sstate.\n\t\n\t// NB no busy_in or result_in as these flag are NOT saved on a per-thread basis\n\n\t// Convert salsaShiftReg to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = salsaShiftReg[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\tend\n\tendgenerate\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of RAM size\n\treg [9:0] writeaddr = 10'd0;\n\n\t// TODO Delayed writeaddr adjusted for ADDRBITS (need to move the bit slicing from wr_addr assignment)\n\t// reg [ADDRBITS-THREADS_BITS:0] writeaddr_d1 = 0;\n\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr_d1 = 10'd0;\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr_d2 = 10'd0;\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr_d3 = 10'd0;\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr_d4 = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\twire [9:0] Xaddr;\n\twire [ADDRBITS-1:0]rd_addr;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0]wr_addr1;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0]wr_addr2;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0]wr_addr3;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0]wr_addr4;\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\treg ram_wren = 1'b0;\n\treg ram_wren_d = 1'b0;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\t// Top ram address is reserved for X0Save/X1save, so adjust\n\t\n\twire [15:0] memtop = 16'hfffe;\t// One less than the top memory location (per THREAD bank)\n\t\n\twire [ADDRBITS-THREADS_BITS-1:0] adj_addr;\n\n\tif (ADDRBITS < 13)\n\t\tassign adj_addr = (Xaddr[9:13-ADDRBITS] == memtop[9:13-ADDRBITS]) ?\n\t\t\t\t\t\t\tmemtop[ADDRBITS-THREADS_BITS-1:0] : Xaddr[9:13-ADDRBITS];\n\telse\n\t\tassign adj_addr = Xaddr;\n\t\n\twire [THREADS_BITS-1:0] phase_addr;\n\t(* S = \"TRUE\" *) reg [THREADS_BITS-1:0] phase_addr_d1;\n\t(* S = \"TRUE\" *) reg [THREADS_BITS-1:0] phase_addr_d2;\n\t(* S = \"TRUE\" *) reg [THREADS_BITS-1:0] phase_addr_d3;\n\t(* S = \"TRUE\" *) reg [THREADS_BITS-1:0] phase_addr_d4;\n\t\n\tassign phase_addr = phase[THREADS_BITS-1:0];\n\t// TODO remove the +1 and just derive wr_addr from phase instead of phase_d2 ?? Maybe this won't work so adj it instead)\n\tassign rd_addr = { phase_addr+1, addrsourceSave_in ? memtop[ADDRBITS-THREADS_BITS:1] : adj_addr };\t// LSB are ignored\n\t\n\tassign wr_addr1 = { phase_addr_d1, writeaddr_d1[9:13-ADDRBITS] };\n\tassign wr_addr2 = { phase_addr_d2, writeaddr_d2[9:13-ADDRBITS] };\n\tassign wr_addr3 = { phase_addr_d3, writeaddr_d3[9:13-ADDRBITS] };\n\tassign wr_addr4 = { phase_addr_d4, writeaddr_d4[9:13-ADDRBITS] };\n\n\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_1 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_2 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_3 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_4 = 0;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr1 = rd_addr | rd_addr_z_1;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr2 = rd_addr | rd_addr_z_2;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr3 = rd_addr | rd_addr_z_3;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr4 = rd_addr | rd_addr_z_4;\n\t\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (rd_addr1, wr_addr1, ram_clk, ram1_din, ram_wren_d, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (rd_addr2, wr_addr2, ram_clk, ram2_din, ram_wren_d, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (rd_addr3, wr_addr3, ram_clk, ram3_din, ram_wren_d, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (rd_addr4, wr_addr4, ram_clk, ram4_din, ram_wren_d, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = addrsourceMix_d ? { Xmix_d, X1out_d} : { X1, X0} ;\t// Registered input\n\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, mixfeedback_d, X0, X1, Xmix, X0out, X1out, Xaddr);\n\n\t// Main multiplexer\n\twire [511:0] Zbits;\n\tassign Zbits = {512{xoren}};\t\t// xoren enables xor from ram (else we load from ram)\n\t\n\t// With luck the synthesizer will interpret this correctly as one-hot control (TODO use explicit signal bits eg Xctl[0] for XSload)\n\tassign X0in = (XCtl==XSmix) ? X1out : (XCtl==XSram) ? ((mixspecial ? X1out : X0out) & Zbits) ^ ramout[511:0] : (XCtl==XSload) ? X[511:0] : X0out;\n\tassign X1in = (XCtl==XSmix) ? Xmix : (XCtl==XSram) ? ((mixspecial ? Xmix : X1out) & Zbits) ^ ramout[1023:512] : (XCtl==XSload) ? X[1023:512] : X1out;\n\t\n\t// Salsa FSM - TODO may want to move this into a separate function (for floorplanning), see hashvariant-C\n\n\t// Hold separate state for each thread (a bit of a kludge to avoid rewriting FSM from scratch)\n\t// NB must ensure shift and result do NOT overlap by carefully controlling timing of start signal\n\t// NB Phase has THREADS+1 cycles, but we do not save the state for (phase==THREADS) as it is never active\n\t\n\tassign { mstate_in, mcount_in, writeaddr_in, cycle_in, doneROM_in, mixfeedback_in, addrsourceMix_in, addrsourceSave_in, mixspecial_in,  intcycles_in} = (phase == THREADS) ? 0 : sstate[phase];\n\n\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\n\treg busy_flag = 1'b0;\n\n`ifdef ONETHREAD\n\t// TEST CONTROLLER ... just allow a single thread to run (busy is currently a common flag)\n\t// NB the thread automatically restarts after it completes, so its a slight misnomer to say it starts once.\n\treg start_once = 1'b0;\n\twire start_flag;\n\tassign start_flag = start & ~start_once;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine\n`else\n\t// NB start_flag only has effect when a thread is at R_IDLE, ie after reset, normally a thread will automatically\n\t// restart on completion. We need to spread the R_IDLE starts evenly to ensure proper ooperation. NB the pbkdf\n\t// engine requires busy and result, but this  looks alter itself in the salsa FSM, even though these are global\n\t// flags. Reset periodically (on loadnonce in pbkdfengine) to ensure it stays in sync.\n\treg [15:0] start_count = 0;\n\t// TODO automatic configuration based on THREADS (currently assumes 8)\n\t// Each lookup_gap=2 salsa takes on average 9 * (8 * 1024 + 8 * (1024*1.5)) = 184320 clocks\n\t// so start 8 threads at 184320 / 8 = 23040 clock intervals\n\t// For lookup_gap=4 use 1024*(4+3+2+1)/4 and for lookup_gap=8 use 1024*(8+..+1)/8 ie 1024*4.5\n\tparameter START_INTERVAL = ((ADDRBITS == 12) ? 184320 : (ADDRBITS == 11) ? 258048 : 405504)\t/ THREADS;\n\treg start_flag = 1'b0;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine - this will toggle on transtion through R_START\n`endif\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tX0 <= X0in;\n\t\tX1 <= X1in;\n\n\t\tif (phase_d != THREADS)\n\t\t\tsstate[phase_d] <= reset ? 0 : { mstate, mcount, writeaddr, cycle, doneROM, mixfeedback, addrsourceMix,\n\t\t\t\t\t\t\t\t\t\t\t\taddrsourceSave, mixspecial, intcycles };\n\t\tmstate <= mstate_in;\t\t// Set defaults (overridden below as necessary)\n\t\tmcount <= mcount_in;\n\t\twriteaddr <= writeaddr_in;\n\t\tcycle <= cycle_in;\n\t\tintcycles <= intcycles_in;\n\t\tdoneROM <= doneROM_in;\n\t\tmixfeedback <= mixfeedback_in;\n\t\taddrsourceMix <= addrsourceMix_in;\n\t\taddrsourceSave <= addrsourceSave_in;\n\t\tmixspecial <= mixspecial_in;\n\t\t\n\t\tmixfeedback_d <= mixfeedback;\t// Fudge\n\t\taddrsourceMix_d <= addrsourceMix;\n\t\tram_wren_d <= ram_wren;\n\n\t\t// TODO move the address slicing from wr_addr to here\n\t\twriteaddr_d1 <= addrsourceMix ? memtop[10:1] : writeaddr;\n\t\twriteaddr_d2 <= addrsourceMix ? memtop[10:1] : writeaddr;\n\t\twriteaddr_d3 <= addrsourceMix ? memtop[10:1] : writeaddr;\n\t\twriteaddr_d4 <= addrsourceMix ? memtop[10:1] : writeaddr;\n\n\t\tphase_addr_d1 <= phase;\n\t\tphase_addr_d2 <= phase;\n\t\tphase_addr_d3 <= phase;\n\t\tphase_addr_d4 <= phase;\n\n\t\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\trd_addr_z_1 <= {ADDRBITS{reset}};\n\t\trd_addr_z_2 <= {ADDRBITS{reset}};\n\t\trd_addr_z_3 <= {ADDRBITS{reset}};\n\t\trd_addr_z_4 <= {ADDRBITS{reset}};\n\t\t\n\t\tXmix_d <= Xmix;\n\t\tX1out_d <= X1out;\n\n\t\tXCtl <= XSnull;\t\t\t\t// Default states\n\t\taddrsourceSave <= 0;\n\t\tram_wren <= 0;\n\t\txoren <= 1;\n\n\t\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\t\t`ifdef ONETHREAD\n\t\tif (start)\n\t\t\tstart_once <= 1'b1;\n\t\tif (reset)\n\t\t\tstart_once <= 1'b0;\n\t\t`else\n\t\tstart_count <= start_count + 1;\n\t\t// start_flag <= 1'b0;\t\t\t// Done below when we transition out of R_IDLE\n\t\tif (reset || start_count == START_INTERVAL)\n\t\tbegin\n\t\t\tstart_count <= 0;\n\t\t\tif (~reset && start)\n\t\t\t\tstart_flag <= 1'b1;\n\t\tend\n\t\t`endif\n\t\t\n\t\t// Could use explicit mux for this ...\n\t\tif (shift)\n\t\tbegin\n\t\t\tsalsaShiftReg <= { salsaShiftReg[1022:0], nonce_sr[31] };\n\t\t\tnonce_sr <= { nonce_sr[30:0], din };\n\t\tend\n\t\telse\n\t\tif (XCtl==XSload && phase_d != THREADS)\t\t// Set at end of previous hash - this is executed regardless of phase\n\t\tbegin\n\t\t\tsalsaShiftReg <= { Xmix, X1out };\t// Simultaneously with XSload\n\t\t\tnonce_sr <= snonce[phase_d];\t\t// NB bidirectional load\n\t\t\tsnonce[phase_d] <= nonce_sr;\n\t\tend\n\t\t\n\t\tif (reset == 1'b1)\n\t\tbegin\n\t\t\tmstate <= R_IDLE;\t\t// This will propagate to all sstate slots as we hold reset for 10 cycles\n\t\t\tbusy_flag <= 1'b0;\n\t\t\tresult <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate_in)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\t// R_IDLE only applies after reset. Normally each thread will reenter at S_START and\n\t\t\t\t\t// assumes that input data is waiting (this relies on the threads being started evenly,\n\t\t\t\t\t// hence the interface FSM at the top of this file)\n\t\t\t\t\tif ((phase!=THREADS) && start_flag)\t// Ensure (phase==THREADS) slot is never active\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSload;\t\t\t// First time only (normally done at end of previous salsa cycle=1023)\n\t\t\t\t\t\t`ifndef ONETHREAD\n\t\t\t\t\t\t\tstart_flag <= 1'b0;\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t\t// Toggle the busy flag low to ack pbkdfengine (its usually already set\n\t\t\t\t\t\t\t\t\t\t\t\t// since other threads are running)\n\t\t\t\t\t\tmstate <= R_START;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_START: begin\t\t\t\t\t// Reentry point after thread completion. ASSUMES new data is ready.\n\t\t\t\t\t\twriteaddr <= 0;\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tcycle <= 0;\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\tmixspecial <= 1'b0;\n\t\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\t\tbusy_flag <= 1'b1;\n\t\t\t\t\t\tresult <= 1'b0;\n\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Initial write cycle\n\t\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\t\tend\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\tmcount <= mcount_in + 6'd1;\n\t\t\t\t\t// 8 stages since salsa takes 4 clock cycles. NB This minimises clock cycles, but adds to\n\t\t\t\t\t// the propagation delay in the salsa. The alternative of adding a cycle or two of latency to\n\t\t\t\t\t// reduce propagation delay is SLOWER due to the extra clocks needed.\n\t\t\t\t\t// Write to ROM every 2nd cycle (NB we are writing previous data here)\n\t\t\t\t\t// NB One extra cycle is performed after ROM is complete to update X0,X1 to inital state for R_MIX\n\t\t\t\t\tif (mcount_in==0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\t\tif (writeaddr_in==1023)\n\t\t\t\t\t\t\tdoneROM <= 1'b1;\t\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\t\twriteaddr <= writeaddr_in + 10'd1;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount_in==4 || mcount_in==8)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount_in==3 || mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount_in==6 && doneROM_in)\t\t\t// Preset the address source one cycle early\n\t\t\t\t\t\taddrsourceMix <= 1'b1;\t\t\t// Remains set for duration of R_MIX\n\t\t\t\t\tif (mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tif (doneROM_in)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t\tmixspecial <= 1'b1;\t\t\t// Remains true throught R_MIX\n\t\t\t\t\t\t\t// Need this to cover the case of the initial read being interpolated\n\t\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_MIX\n\t\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr[12-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\t\tif ( Xaddr[9:13-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr[12-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\t\tif ( (Xaddr[9:13-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr[12-ADDRBITSX:0] )\n\t\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t\t// Setup to save at mcount_in==0 (also does so entering R_IDLE\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t\t// after cycle==1023 but of no consequence)\n\t\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\t\t\tram_wren <= ~|writeaddr_in[12-ADDRBITSX:0];\t// Only write non-interpolated addresses\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// Entered with mixfeedback == 0 (set at mcount_in==7 above)\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\t// The longest chain is from mixfeedback to ram address input (since XMix is not registered),\n\t\t\t\t\t// again as noted above, extra register stages would simply reduce throughput.\n\t\t\t\t\tmcount <= mcount_in + 6'd1;\n\t\t\t\t\tif (mcount_in==0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\t\tif (intcycles_in != 0)\t\t// Set in previous cycle\n\t\t\t\t\t\t\tmstate <= R_INT;\t\t// Interpolate\n\t\t\t\t\tend\n\n\t\t\t\t\tif (mcount_in==4 || mcount_in==8)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount_in==3 || mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tend\n\n\t\t\t\t\tif (mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcycle <= cycle_in + 11'd1;\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tif (cycle_in==1023)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tbusy_flag <= 1'b0;\t// Will hold at 0 for 9 clocks until set at R_START\n\t\t\t\t\t\t\tif (start)\t\t\t// Check data input is ready\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tXCtl <= XSload;\t\t// Initial load else we overwrite input NB This is\n\t\t\t\t\t\t\t\t\t\t\t\t\t// executed on the next cycle, regardless of phase\n\t\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\t\tmstate <= R_START;\t// Restart immediately\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tmstate <= R_IDLE;\t// Wait for start_flag\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_WRITE\n\t\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr[12-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\t\tif ( Xaddr[9:13-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr[12-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\t\tif ( (Xaddr[9:13-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr[12-ADDRBITSX:0] )\n\t\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t\t// Setup to save at mcount_in==0 (also does so entering R_IDLE\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t\t// after cycle==1023 but of no consequence)\n\t\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\t\t\n\t\t\t\tend\n\n\t\t\t\tR_INT: begin\n\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\t// Mcount has already been incremented in R_MIX\n\t\t\t\t\tmcount <= mcount_in + 6'd1;\n\t\t\t\t\tif (mcount_in==4 || mcount_in==8)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount_in==3 || mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tend\n\n\t\t\t\t\tif (mcount_in==6)\n\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data at mcount_in==8\n\n\t\t\t\t\tif (mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (intcycles_in==1)\n\t\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Setup to XOR from saved X0/X1 in ram at next cycle\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount_in==8)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tintcycles <= intcycles_in - 1;\n\t\t\t\t\t\tmcount <= 1;\t\t// Skip 0 since done above\n\t\t\t\t\t\tif (intcycles_in==1)\n\t\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\t// Else mstate remains at R_INT so we continue interpolating from mcount=1\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (mstate==R_MIX && mcount==0)\n\t\t$display (\"phase %d cycle %d Xmix %08x\\n\", phase, cycle-1, Xmix[511:480]);\n`endif\n\tend\t// always @(posedge hash_clk)\nendmodule"
  },
  {
    "path": "experimental/LX150-EIGHT-A/sgen.c",
    "content": "#include \"stdio.h\"\nint main()\n{\n\tint i; char c;\n\n\tfor (i=0; i<16; i++)\n\t\t\tprintf(\"reg [31:0] x%02dd1, x%02dd2, x%02dd3, x%02dd4, x%02dd5, x%02dd6, x%02dd7, x%02dd8, x%02dd9;\\n\",i,i,i,i,i,i,i,i,i);\n\t\t\t\n\tfor (i=0; i<16; i++)\n\t\t\tprintf(\"reg [31:0] c%02d, c%02dd1, c%02dd2, c%02dd3, c%02dd4, c%02dd5, c%02dd6, c%02dd7, c%02dd8, c%02dd9;\\n\",i,i,i,i,i,i,i,i,i,i);\n\n\tfor (i=0; i<16; i++)\n\t\t\tprintf(\"reg [31:0] r%02d, r%02dd1, r%02dd2, r%02dd3, r%02dd4, r%02dd5, r%02dd6, r%02dd7, r%02dd8, r%02dd9;\\n\",i,i,i,i,i,i,i,i,i,i);\n\n\tprintf(\"always @ (posedge clk)\\nbegin\\n\");\n\n\tc = 'x';\n\tfor (i=0; i<16; i++)\n\t{\n\t\tprintf (\"%c%02dd1 <= %c%02d;\\n\",  c, i, c, i);\n\t\tprintf (\"%c%02dd2 <= %c%02dd1;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd3 <= %c%02dd2;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd4 <= %c%02dd3;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd5 <= %c%02dd4;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd6 <= %c%02dd5;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd7 <= %c%02dd6;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd8 <= %c%02dd7;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd9 <= %c%02dd8;\\n\", c, i, c, i);\n\t}\n\t\n\tc = 'c';\n\tfor (i=0; i<16; i++)\n\t{\n\t\tprintf (\"%c%02dd1 <= %c%02d;\\n\",  c, i, c, i);\n\t\tprintf (\"%c%02dd2 <= %c%02dd1;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd3 <= %c%02dd2;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd4 <= %c%02dd3;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd5 <= %c%02dd4;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd6 <= %c%02dd5;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd7 <= %c%02dd6;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd8 <= %c%02dd7;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd9 <= %c%02dd8;\\n\", c, i, c, i);\n\t}\n\t\n\tc = 'r';\n\tfor (i=0; i<16; i++)\n\t{\n\t\tprintf (\"%c%02dd1 <= %c%02d;\\n\",  c, i, c, i);\n\t\tprintf (\"%c%02dd2 <= %c%02dd1;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd3 <= %c%02dd2;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd4 <= %c%02dd3;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd5 <= %c%02dd4;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd6 <= %c%02dd5;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd7 <= %c%02dd6;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd8 <= %c%02dd7;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd9 <= %c%02dd8;\\n\", c, i, c, i);\n\t}\n\t\n\tprintf(\"end\\n\");\n\treturn 0;\n}\n"
  },
  {
    "path": "experimental/LX150-EIGHT-A/sgen.inc",
    "content": "reg [31:0] x00d1, x00d2, x00d3, x00d4, x00d5, x00d6, x00d7, x00d8, x00d9;\nreg [31:0] x01d1, x01d2, x01d3, x01d4, x01d5, x01d6, x01d7, x01d8, x01d9;\nreg [31:0] x02d1, x02d2, x02d3, x02d4, x02d5, x02d6, x02d7, x02d8, x02d9;\nreg [31:0] x03d1, x03d2, x03d3, x03d4, x03d5, x03d6, x03d7, x03d8, x03d9;\nreg [31:0] x04d1, x04d2, x04d3, x04d4, x04d5, x04d6, x04d7, x04d8, x04d9;\nreg [31:0] x05d1, x05d2, x05d3, x05d4, x05d5, x05d6, x05d7, x05d8, x05d9;\nreg [31:0] x06d1, x06d2, x06d3, x06d4, x06d5, x06d6, x06d7, x06d8, x06d9;\nreg [31:0] x07d1, x07d2, x07d3, x07d4, x07d5, x07d6, x07d7, x07d8, x07d9;\nreg [31:0] x08d1, x08d2, x08d3, x08d4, x08d5, x08d6, x08d7, x08d8, x08d9;\nreg [31:0] x09d1, x09d2, x09d3, x09d4, x09d5, x09d6, x09d7, x09d8, x09d9;\nreg [31:0] x10d1, x10d2, x10d3, x10d4, x10d5, x10d6, x10d7, x10d8, x10d9;\nreg [31:0] x11d1, x11d2, x11d3, x11d4, x11d5, x11d6, x11d7, x11d8, x11d9;\nreg [31:0] x12d1, x12d2, x12d3, x12d4, x12d5, x12d6, x12d7, x12d8, x12d9;\nreg [31:0] x13d1, x13d2, x13d3, x13d4, x13d5, x13d6, x13d7, x13d8, x13d9;\nreg [31:0] x14d1, x14d2, x14d3, x14d4, x14d5, x14d6, x14d7, x14d8, x14d9;\nreg [31:0] x15d1, x15d2, x15d3, x15d4, x15d5, x15d6, x15d7, x15d8, x15d9;\nreg [31:0] c00, c00d1, c00d2, c00d3, c00d4, c00d5, c00d6, c00d7, c00d8, c00d9;\nreg [31:0] c01, c01d1, c01d2, c01d3, c01d4, c01d5, c01d6, c01d7, c01d8, c01d9;\nreg [31:0] c02, c02d1, c02d2, c02d3, c02d4, c02d5, c02d6, c02d7, c02d8, c02d9;\nreg [31:0] c03, c03d1, c03d2, c03d3, c03d4, c03d5, c03d6, c03d7, c03d8, c03d9;\nreg [31:0] c04, c04d1, c04d2, c04d3, c04d4, c04d5, c04d6, c04d7, c04d8, c04d9;\nreg [31:0] c05, c05d1, c05d2, c05d3, c05d4, c05d5, c05d6, c05d7, c05d8, c05d9;\nreg [31:0] c06, c06d1, c06d2, c06d3, c06d4, c06d5, c06d6, c06d7, c06d8, c06d9;\nreg [31:0] c07, c07d1, c07d2, c07d3, c07d4, c07d5, c07d6, c07d7, c07d8, c07d9;\nreg [31:0] c08, c08d1, c08d2, c08d3, c08d4, c08d5, c08d6, c08d7, c08d8, c08d9;\nreg [31:0] c09, c09d1, c09d2, c09d3, c09d4, c09d5, c09d6, c09d7, c09d8, c09d9;\nreg [31:0] c10, c10d1, c10d2, c10d3, c10d4, c10d5, c10d6, c10d7, c10d8, c10d9;\nreg [31:0] c11, c11d1, c11d2, c11d3, c11d4, c11d5, c11d6, c11d7, c11d8, c11d9;\nreg [31:0] c12, c12d1, c12d2, c12d3, c12d4, c12d5, c12d6, c12d7, c12d8, c12d9;\nreg [31:0] c13, c13d1, c13d2, c13d3, c13d4, c13d5, c13d6, c13d7, c13d8, c13d9;\nreg [31:0] c14, c14d1, c14d2, c14d3, c14d4, c14d5, c14d6, c14d7, c14d8, c14d9;\nreg [31:0] c15, c15d1, c15d2, c15d3, c15d4, c15d5, c15d6, c15d7, c15d8, c15d9;\nreg [31:0] r00, r00d1, r00d2, r00d3, r00d4, r00d5, r00d6, r00d7, r00d8, r00d9;\nreg [31:0] r01, r01d1, r01d2, r01d3, r01d4, r01d5, r01d6, r01d7, r01d8, r01d9;\nreg [31:0] r02, r02d1, r02d2, r02d3, r02d4, r02d5, r02d6, r02d7, r02d8, r02d9;\nreg [31:0] r03, r03d1, r03d2, r03d3, r03d4, r03d5, r03d6, r03d7, r03d8, r03d9;\nreg [31:0] r04, r04d1, r04d2, r04d3, r04d4, r04d5, r04d6, r04d7, r04d8, r04d9;\nreg [31:0] r05, r05d1, r05d2, r05d3, r05d4, r05d5, r05d6, r05d7, r05d8, r05d9;\nreg [31:0] r06, r06d1, r06d2, r06d3, r06d4, r06d5, r06d6, r06d7, r06d8, r06d9;\nreg [31:0] r07, r07d1, r07d2, r07d3, r07d4, r07d5, r07d6, r07d7, r07d8, r07d9;\nreg [31:0] r08, r08d1, r08d2, r08d3, r08d4, r08d5, r08d6, r08d7, r08d8, r08d9;\nreg [31:0] r09, r09d1, r09d2, r09d3, r09d4, r09d5, r09d6, r09d7, r09d8, r09d9;\nreg [31:0] r10, r10d1, r10d2, r10d3, r10d4, r10d5, r10d6, r10d7, r10d8, r10d9;\nreg [31:0] r11, r11d1, r11d2, r11d3, r11d4, r11d5, r11d6, r11d7, r11d8, r11d9;\nreg [31:0] r12, r12d1, r12d2, r12d3, r12d4, r12d5, r12d6, r12d7, r12d8, r12d9;\nreg [31:0] r13, r13d1, r13d2, r13d3, r13d4, r13d5, r13d6, r13d7, r13d8, r13d9;\nreg [31:0] r14, r14d1, r14d2, r14d3, r14d4, r14d5, r14d6, r14d7, r14d8, r14d9;\nreg [31:0] r15, r15d1, r15d2, r15d3, r15d4, r15d5, r15d6, r15d7, r15d8, r15d9;\nalways @ (posedge clk)\nbegin\nx00d1 <= x00;\nx00d2 <= x00d1;\nx00d3 <= x00d2;\nx00d4 <= x00d3;\nx00d5 <= x00d4;\nx00d6 <= x00d5;\nx00d7 <= x00d6;\nx00d8 <= x00d7;\nx00d9 <= x00d8;\nx01d1 <= x01;\nx01d2 <= x01d1;\nx01d3 <= x01d2;\nx01d4 <= x01d3;\nx01d5 <= x01d4;\nx01d6 <= x01d5;\nx01d7 <= x01d6;\nx01d8 <= x01d7;\nx01d9 <= x01d8;\nx02d1 <= x02;\nx02d2 <= x02d1;\nx02d3 <= x02d2;\nx02d4 <= x02d3;\nx02d5 <= x02d4;\nx02d6 <= x02d5;\nx02d7 <= x02d6;\nx02d8 <= x02d7;\nx02d9 <= x02d8;\nx03d1 <= x03;\nx03d2 <= x03d1;\nx03d3 <= x03d2;\nx03d4 <= x03d3;\nx03d5 <= x03d4;\nx03d6 <= x03d5;\nx03d7 <= x03d6;\nx03d8 <= x03d7;\nx03d9 <= x03d8;\nx04d1 <= x04;\nx04d2 <= x04d1;\nx04d3 <= x04d2;\nx04d4 <= x04d3;\nx04d5 <= x04d4;\nx04d6 <= x04d5;\nx04d7 <= x04d6;\nx04d8 <= x04d7;\nx04d9 <= x04d8;\nx05d1 <= x05;\nx05d2 <= x05d1;\nx05d3 <= x05d2;\nx05d4 <= x05d3;\nx05d5 <= x05d4;\nx05d6 <= x05d5;\nx05d7 <= x05d6;\nx05d8 <= x05d7;\nx05d9 <= x05d8;\nx06d1 <= x06;\nx06d2 <= x06d1;\nx06d3 <= x06d2;\nx06d4 <= x06d3;\nx06d5 <= x06d4;\nx06d6 <= x06d5;\nx06d7 <= x06d6;\nx06d8 <= x06d7;\nx06d9 <= x06d8;\nx07d1 <= x07;\nx07d2 <= x07d1;\nx07d3 <= x07d2;\nx07d4 <= x07d3;\nx07d5 <= x07d4;\nx07d6 <= x07d5;\nx07d7 <= x07d6;\nx07d8 <= x07d7;\nx07d9 <= x07d8;\nx08d1 <= x08;\nx08d2 <= x08d1;\nx08d3 <= x08d2;\nx08d4 <= x08d3;\nx08d5 <= x08d4;\nx08d6 <= x08d5;\nx08d7 <= x08d6;\nx08d8 <= x08d7;\nx08d9 <= x08d8;\nx09d1 <= x09;\nx09d2 <= x09d1;\nx09d3 <= x09d2;\nx09d4 <= x09d3;\nx09d5 <= x09d4;\nx09d6 <= x09d5;\nx09d7 <= x09d6;\nx09d8 <= x09d7;\nx09d9 <= x09d8;\nx10d1 <= x10;\nx10d2 <= x10d1;\nx10d3 <= x10d2;\nx10d4 <= x10d3;\nx10d5 <= x10d4;\nx10d6 <= x10d5;\nx10d7 <= x10d6;\nx10d8 <= x10d7;\nx10d9 <= x10d8;\nx11d1 <= x11;\nx11d2 <= x11d1;\nx11d3 <= x11d2;\nx11d4 <= x11d3;\nx11d5 <= x11d4;\nx11d6 <= x11d5;\nx11d7 <= x11d6;\nx11d8 <= x11d7;\nx11d9 <= x11d8;\nx12d1 <= x12;\nx12d2 <= x12d1;\nx12d3 <= x12d2;\nx12d4 <= x12d3;\nx12d5 <= x12d4;\nx12d6 <= x12d5;\nx12d7 <= x12d6;\nx12d8 <= x12d7;\nx12d9 <= x12d8;\nx13d1 <= x13;\nx13d2 <= x13d1;\nx13d3 <= x13d2;\nx13d4 <= x13d3;\nx13d5 <= x13d4;\nx13d6 <= x13d5;\nx13d7 <= x13d6;\nx13d8 <= x13d7;\nx13d9 <= x13d8;\nx14d1 <= x14;\nx14d2 <= x14d1;\nx14d3 <= x14d2;\nx14d4 <= x14d3;\nx14d5 <= x14d4;\nx14d6 <= x14d5;\nx14d7 <= x14d6;\nx14d8 <= x14d7;\nx14d9 <= x14d8;\nx15d1 <= x15;\nx15d2 <= x15d1;\nx15d3 <= x15d2;\nx15d4 <= x15d3;\nx15d5 <= x15d4;\nx15d6 <= x15d5;\nx15d7 <= x15d6;\nx15d8 <= x15d7;\nx15d9 <= x15d8;\nc00d1 <= c00;\nc00d2 <= c00d1;\nc00d3 <= c00d2;\nc00d4 <= c00d3;\nc00d5 <= c00d4;\nc00d6 <= c00d5;\nc00d7 <= c00d6;\nc00d8 <= c00d7;\nc00d9 <= c00d8;\nc01d1 <= c01;\nc01d2 <= c01d1;\nc01d3 <= c01d2;\nc01d4 <= c01d3;\nc01d5 <= c01d4;\nc01d6 <= c01d5;\nc01d7 <= c01d6;\nc01d8 <= c01d7;\nc01d9 <= c01d8;\nc02d1 <= c02;\nc02d2 <= c02d1;\nc02d3 <= c02d2;\nc02d4 <= c02d3;\nc02d5 <= c02d4;\nc02d6 <= c02d5;\nc02d7 <= c02d6;\nc02d8 <= c02d7;\nc02d9 <= c02d8;\nc03d1 <= c03;\nc03d2 <= c03d1;\nc03d3 <= c03d2;\nc03d4 <= c03d3;\nc03d5 <= c03d4;\nc03d6 <= c03d5;\nc03d7 <= c03d6;\nc03d8 <= c03d7;\nc03d9 <= c03d8;\nc04d1 <= c04;\nc04d2 <= c04d1;\nc04d3 <= c04d2;\nc04d4 <= c04d3;\nc04d5 <= c04d4;\nc04d6 <= c04d5;\nc04d7 <= c04d6;\nc04d8 <= c04d7;\nc04d9 <= c04d8;\nc05d1 <= c05;\nc05d2 <= c05d1;\nc05d3 <= c05d2;\nc05d4 <= c05d3;\nc05d5 <= c05d4;\nc05d6 <= c05d5;\nc05d7 <= c05d6;\nc05d8 <= c05d7;\nc05d9 <= c05d8;\nc06d1 <= c06;\nc06d2 <= c06d1;\nc06d3 <= c06d2;\nc06d4 <= c06d3;\nc06d5 <= c06d4;\nc06d6 <= c06d5;\nc06d7 <= c06d6;\nc06d8 <= c06d7;\nc06d9 <= c06d8;\nc07d1 <= c07;\nc07d2 <= c07d1;\nc07d3 <= c07d2;\nc07d4 <= c07d3;\nc07d5 <= c07d4;\nc07d6 <= c07d5;\nc07d7 <= c07d6;\nc07d8 <= c07d7;\nc07d9 <= c07d8;\nc08d1 <= c08;\nc08d2 <= c08d1;\nc08d3 <= c08d2;\nc08d4 <= c08d3;\nc08d5 <= c08d4;\nc08d6 <= c08d5;\nc08d7 <= c08d6;\nc08d8 <= c08d7;\nc08d9 <= c08d8;\nc09d1 <= c09;\nc09d2 <= c09d1;\nc09d3 <= c09d2;\nc09d4 <= c09d3;\nc09d5 <= c09d4;\nc09d6 <= c09d5;\nc09d7 <= c09d6;\nc09d8 <= c09d7;\nc09d9 <= c09d8;\nc10d1 <= c10;\nc10d2 <= c10d1;\nc10d3 <= c10d2;\nc10d4 <= c10d3;\nc10d5 <= c10d4;\nc10d6 <= c10d5;\nc10d7 <= c10d6;\nc10d8 <= c10d7;\nc10d9 <= c10d8;\nc11d1 <= c11;\nc11d2 <= c11d1;\nc11d3 <= c11d2;\nc11d4 <= c11d3;\nc11d5 <= c11d4;\nc11d6 <= c11d5;\nc11d7 <= c11d6;\nc11d8 <= c11d7;\nc11d9 <= c11d8;\nc12d1 <= c12;\nc12d2 <= c12d1;\nc12d3 <= c12d2;\nc12d4 <= c12d3;\nc12d5 <= c12d4;\nc12d6 <= c12d5;\nc12d7 <= c12d6;\nc12d8 <= c12d7;\nc12d9 <= c12d8;\nc13d1 <= c13;\nc13d2 <= c13d1;\nc13d3 <= c13d2;\nc13d4 <= c13d3;\nc13d5 <= c13d4;\nc13d6 <= c13d5;\nc13d7 <= c13d6;\nc13d8 <= c13d7;\nc13d9 <= c13d8;\nc14d1 <= c14;\nc14d2 <= c14d1;\nc14d3 <= c14d2;\nc14d4 <= c14d3;\nc14d5 <= c14d4;\nc14d6 <= c14d5;\nc14d7 <= c14d6;\nc14d8 <= c14d7;\nc14d9 <= c14d8;\nc15d1 <= c15;\nc15d2 <= c15d1;\nc15d3 <= c15d2;\nc15d4 <= c15d3;\nc15d5 <= c15d4;\nc15d6 <= c15d5;\nc15d7 <= c15d6;\nc15d8 <= c15d7;\nc15d9 <= c15d8;\nr00d1 <= r00;\nr00d2 <= r00d1;\nr00d3 <= r00d2;\nr00d4 <= r00d3;\nr00d5 <= r00d4;\nr00d6 <= r00d5;\nr00d7 <= r00d6;\nr00d8 <= r00d7;\nr00d9 <= r00d8;\nr01d1 <= r01;\nr01d2 <= r01d1;\nr01d3 <= r01d2;\nr01d4 <= r01d3;\nr01d5 <= r01d4;\nr01d6 <= r01d5;\nr01d7 <= r01d6;\nr01d8 <= r01d7;\nr01d9 <= r01d8;\nr02d1 <= r02;\nr02d2 <= r02d1;\nr02d3 <= r02d2;\nr02d4 <= r02d3;\nr02d5 <= r02d4;\nr02d6 <= r02d5;\nr02d7 <= r02d6;\nr02d8 <= r02d7;\nr02d9 <= r02d8;\nr03d1 <= r03;\nr03d2 <= r03d1;\nr03d3 <= r03d2;\nr03d4 <= r03d3;\nr03d5 <= r03d4;\nr03d6 <= r03d5;\nr03d7 <= r03d6;\nr03d8 <= r03d7;\nr03d9 <= r03d8;\nr04d1 <= r04;\nr04d2 <= r04d1;\nr04d3 <= r04d2;\nr04d4 <= r04d3;\nr04d5 <= r04d4;\nr04d6 <= r04d5;\nr04d7 <= r04d6;\nr04d8 <= r04d7;\nr04d9 <= r04d8;\nr05d1 <= r05;\nr05d2 <= r05d1;\nr05d3 <= r05d2;\nr05d4 <= r05d3;\nr05d5 <= r05d4;\nr05d6 <= r05d5;\nr05d7 <= r05d6;\nr05d8 <= r05d7;\nr05d9 <= r05d8;\nr06d1 <= r06;\nr06d2 <= r06d1;\nr06d3 <= r06d2;\nr06d4 <= r06d3;\nr06d5 <= r06d4;\nr06d6 <= r06d5;\nr06d7 <= r06d6;\nr06d8 <= r06d7;\nr06d9 <= r06d8;\nr07d1 <= r07;\nr07d2 <= r07d1;\nr07d3 <= r07d2;\nr07d4 <= r07d3;\nr07d5 <= r07d4;\nr07d6 <= r07d5;\nr07d7 <= r07d6;\nr07d8 <= r07d7;\nr07d9 <= r07d8;\nr08d1 <= r08;\nr08d2 <= r08d1;\nr08d3 <= r08d2;\nr08d4 <= r08d3;\nr08d5 <= r08d4;\nr08d6 <= r08d5;\nr08d7 <= r08d6;\nr08d8 <= r08d7;\nr08d9 <= r08d8;\nr09d1 <= r09;\nr09d2 <= r09d1;\nr09d3 <= r09d2;\nr09d4 <= r09d3;\nr09d5 <= r09d4;\nr09d6 <= r09d5;\nr09d7 <= r09d6;\nr09d8 <= r09d7;\nr09d9 <= r09d8;\nr10d1 <= r10;\nr10d2 <= r10d1;\nr10d3 <= r10d2;\nr10d4 <= r10d3;\nr10d5 <= r10d4;\nr10d6 <= r10d5;\nr10d7 <= r10d6;\nr10d8 <= r10d7;\nr10d9 <= r10d8;\nr11d1 <= r11;\nr11d2 <= r11d1;\nr11d3 <= r11d2;\nr11d4 <= r11d3;\nr11d5 <= r11d4;\nr11d6 <= r11d5;\nr11d7 <= r11d6;\nr11d8 <= r11d7;\nr11d9 <= r11d8;\nr12d1 <= r12;\nr12d2 <= r12d1;\nr12d3 <= r12d2;\nr12d4 <= r12d3;\nr12d5 <= r12d4;\nr12d6 <= r12d5;\nr12d7 <= r12d6;\nr12d8 <= r12d7;\nr12d9 <= r12d8;\nr13d1 <= r13;\nr13d2 <= r13d1;\nr13d3 <= r13d2;\nr13d4 <= r13d3;\nr13d5 <= r13d4;\nr13d6 <= r13d5;\nr13d7 <= r13d6;\nr13d8 <= r13d7;\nr13d9 <= r13d8;\nr14d1 <= r14;\nr14d2 <= r14d1;\nr14d3 <= r14d2;\nr14d4 <= r14d3;\nr14d5 <= r14d4;\nr14d6 <= r14d5;\nr14d7 <= r14d6;\nr14d8 <= r14d7;\nr14d9 <= r14d8;\nr15d1 <= r15;\nr15d2 <= r15d1;\nr15d3 <= r15d2;\nr15d4 <= r15d3;\nr15d5 <= r15d4;\nr15d6 <= r15d5;\nr15d7 <= r15d6;\nr15d8 <= r15d7;\nr15d9 <= r15d8;\nend\n"
  },
  {
    "path": "experimental/LX150-EIGHT-A/test_icarus.v",
    "content": "// Testbench for ltcminer_icarus.v\n\n`timescale 1ns/1ps\n\n`ifdef SIM\t\t\t\t\t// Avoids wrong top selected if included in ISE/PlanAhead sources\nmodule test_ltcminer ();\n\n\treg clk = 1'b0;\n\treg [31:0] cycle = 32'd0;\n\n\tinitial begin\n\t\tclk = 0;\n\t\t\n\t\twhile(1)\n\t\tbegin\n\t\t\t#5 clk = 1; #5 clk = 0;\n\t\tend\n\tend\n\n\talways @ (posedge clk)\n\tbegin\n\t\tcycle <= cycle + 32'd1;\n\tend\n\t\n\t// Running with default zero's for the data1..3 regs.\n\t// tx_hash=553a4b69b43913a61b42013ce210f713eaa7332e48cda1bdf3b93b10161d0876 at 187,990 nS and\n\t// final_hash (if SIM is defined) at 188,000 nS with golden_nonce_match flag NOT set since it is\n\t// not a diff=32 share. To test golden_nonce, just tweak the target eg 31'hffffffff will match everything\n\t\n\t// With serial input(at comm_clk_frequency=1_000_000), we get rx_done at t=70,220nS, however there is already a\n\t// PBKDF2_SHA256_80_128 loaded in Xbuf (for nonce=00000001). The first final_hash at 188,000 nS is corrupted as\n\t// the input data has changed from all 0's. The Xbuf starts salsa rom at t=188,000 but the nonce is incorrectly\n\t// taken from the newly loaded data so once salsa in complete it also generates a corrupt final_hash at ~362,000 nS.\n\t// Nonce is incremented then the newly loaded data starts PBKDF2_SHA256_80_128, so we must supply a nonce 1 less\n\t// than the expected golden_nonce. The correct PBKDF2_SHA256_80_128 is ready at ~ 197,000 nS. We get final_hash for\n\t// the corrupted work at ~362,000 nS then our required golden_nonce is at 536,180 nS.\n\t// This is only really a problem for simulation. With live hashing we just lose 2 nonces every time getwork is\n\t// loaded, which isn't a big deal.\n\t\t\n\twire RxD;\n\twire TxD;\n\twire extminer_rxd = 0;\n\twire extminer_txd;\n\twire [3:0] dip = 0;\n\twire [3:0] led;\n\twire TMP_SCL=1, TMP_SDA=1, TMP_ALERT=1;\n\t\n\tparameter comm_clk_frequency = 1_000_000;\t// Speeds up serial loading enormously rx_done is at t=70,220nS\n\tparameter baud_rate = 115_200;\n\t\n\tltcminer_icarus #(.comm_clk_frequency(comm_clk_frequency)) uut\n\t\t(clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\t// Send serial data - 84 bytes, matches on nonce 318f (included in data)\n\t// NB starting nonce is 381e NOT 381f (see note above)\n\treg [671:0] data = 672'h000007ff0000318e7e71441b141fe951b2b0c7dfc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af75575618e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\t\n\treg\t\t\tserial_send = 0;\n\twire\t\tserial_busy;\n\treg [31:0]\tdata_32 = 0;\n\treg [31:0]\tstart_cycle = 0;\n\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(baud_rate)) sertx (.clk(clk), .TxD(RxD), .send(serial_send), .busy(serial_busy), .word(data_32));\n\n\t// TUNE this according to comm_clk_frequency so we send a single getwork (else it gets overwritten with 0's)\n\t// parameter stop_cycle = 7020;\t\t// For comm_clk_frequency=1_000_000\n\tparameter stop_cycle = 0;\t\t\t// Use this to DISABLE sending data\n\talways @ (posedge clk)\n\tbegin\n\t\tserial_send <= 0;\t\t\t\t// Default\n\t\t// Send data every time tx goes idle (NB the !serial_send is to prevent serial_send\n\t\t// going high for two cycles since serial_busy arrives one cycle after serial_send)\n\t\tif (cycle > 5 && cycle < stop_cycle && !serial_busy && !serial_send)\n\t\tbegin\n\t\t\tserial_send <= 1;\n\t\t\tdata_32 <= data[671:640];\n\t\t\tdata <= { data[639:0], 32'd0 };\n\t\t\tstart_cycle <= cycle;\t\t// Remember each start cycle (makes debugging easier)\n\t\tend\n\tend\n\nendmodule\n`endif"
  },
  {
    "path": "experimental/LX150-EIGHT-A/xilinx_dpram.v",
    "content": "// xilinx_ram.v - inferring the ram seems to work fine\n\nmodule ram # ( parameter ADDRBITS=10 ) (\n\traddr,\n\twaddr,\n\tclock,\n\tdata,\n\twren,\n\tq);\n\n\tinput\t[ADDRBITS-1:0]  raddr;\n\tinput\t[ADDRBITS-1:0]  waddr;\n\tinput\t  clock;\n\tinput\t[255:0]  data;\n\tinput\t  wren;\n\toutput\t[255:0]  q;\n\n\t//synthesis attribute ram_style of store is block\n\treg [255:0] store [(2 << (ADDRBITS-1))-1:0];\n\treg[ADDRBITS-1:0] raddr_reg;\n\t\n\talways @ (posedge clock)\n\tbegin\n\t\traddr_reg <= raddr;\n\t\tif (wren)\n\t\t\tstore[waddr] <= data;\n\tend\n\t\n\tassign q = store[raddr_reg];\n\t\t\t\nendmodule"
  },
  {
    "path": "experimental/LX150-EIGHT-B/README.txt",
    "content": "LX150-EIGHT-B\n\nEight threads running through a fully pipelined salsa (though we still roll it\nfour times and repeat for the block mix). Automatically sets the LOOKAHEAD_GAP\nto 2,4, or 8 depending on the number of cores selected.\n\nLX150-EIGHT-B improves on LX150-EIGHT-A by having separate clock domains for\npbkdfengine and salsaengine. It also implements a dynamic clocking scheme using\nDCM_CLKGEN, though treat this with caution as it can lock up occasionally (the\ncode needs some work, I'm not even sure which clock edge I should be using).\n\nThis needs to run at > 100MHz to match the original 25MHz unpipelined code,\nwhich it comes close to achieving. Further work on fanout (the RAM address is\nparticularily slow and may need an additional pipeline stage) could help.\n\nThe code is still rather buggy. There is a 5% to 10% loss of shares which is\npossibly down to the periodic reset on loadnonce, which is required to keep the\npipeline in sync as thread execution time is variable.\n\nThe original ltcminer.py driver will work, but to take advantage of the dyn_pll\nuse ltcminer-dynclock.py and ltcminer-test-dynclock.py, simply run these with\nthe clock speed (in MHZ) as a command line argument, eg.\npython ltcminer-dynclock.py 75\n\nNB There is a hard coded SPEED_LIMIT in ltcminer_icarus.v that sets the max\nvalue for clock. Any attempt to exceed this is silently ignored (currently set\nat 100MHz, increase it at your own risk - check for overheating/overcurrent).\nLow values (less than 25MHz) are also prohibited as there is a tendancy for\nthe DCM to lock up (currently only reprogramming can reset it as I have not\nimplemented a watchdog yet).\n\nThe current version flashes the TxD led in time with the clock to give some\nfeedback that the dynamic configuration is working. You can turn this off by\ncommenting out the `define FLASHCLOCK line at the bottom of ltcminer_icarus.v\nNB The counter resets on loadnonce (to keep the leds in sync, as it just looks\nmessy otherwise), so if your askrate is fast and the clock slow, then the leds\nmay not light at all (until you stop the mining script)."
  },
  {
    "path": "experimental/LX150-EIGHT-B/dyn_pll_ctrl.v",
    "content": "module dyn_pll_ctrl # (parameter SPEED_MHZ = 25, parameter SPEED_LIMIT = 100, parameter SPEED_MIN = 25, parameter OSC_MHZ = 100)\n\t(clk,\n\tclk_valid,\n\tspeed_in,\n\tstart,\n\tprogclk,\n\tprogdata,\n\tprogen,\n\treset,\n\tlocked,\n\tstatus);\n\n\tinput clk;\t\t\t\t// NB Assumed to be 12.5MHz uart_clk\n\tinput clk_valid;\t\t// Drive from LOCKED output of first dcm (ie uart_clk valid)\n\tinput [7:0] speed_in;\n\tinput start;\n\toutput reg progclk = 0;\n\toutput reg progdata = 0;\n\toutput reg progen = 0;\n\toutput reg reset = 0;\n\tinput locked;\n\tinput [2:1] status;\n\n\t// NB spec says to use (dval-1) and (mval-1), but I don't think we need to be that accurate\n\t//    and this saves an adder. Feel free to amend it.\n\treg [23:0] watchdog = 0;\n\treg [7:0] state = 0;\n\treg [7:0] dval = OSC_MHZ;\t// Osc clock speed (hence mval scales in MHz)\n\treg [7:0] mval = SPEED_MHZ;\n\treg start_d1 = 0;\n\t\n\talways @ (posedge clk)\n\tbegin\n\t\tprogclk <= ~progclk;\n\t\tstart_d1 <= start;\n\t\treset <= 1'b0;\n\t\t\n\t\t// Watchdog is just using locked, perhaps also need | ~status[2]\n\t\tif (locked)\n\t\t\twatchdog <= 0;\n\t\telse\n\t\t\twatchdog <= watchdog + 1'b1;\n\t\t\n\t\tif (watchdog[23])\t\t// Approx 670mS at 12.5MHz - NB spec is 5ms to lock at >50MHz CLKIN (50ms at <50MHz CLKIN)\n\t\tbegin\t\t\t\t\t// but allow longer just in case\n\t\t\twatchdog <= 0;\n\t\t\treset <= 1'b1;\t\t// One cycle at 12.5MHz should suffice (requirment is 3 CLKIN at 100MHz)\n\t\tend\n\t\t\n\t\tif (~clk_valid)\t\t\t// Try not to run while clk is unstable\n\t\tbegin\n\t\t\tprogen <= 0;\n\t\t\tprogdata <= 0;\n\t\t\tstate <= 0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\n\t\t\t// The documentation is unclear as to whether the DCM loads data on positive or negative edge. The timing\n\t\t\t// diagram unhelpfully shows data changing on the positive edge, which could mean either its sampled on\n\t\t\t// negative, or it was clocked on positive! However the following (WRONGLY) says NEGATIVE ...\n\t\t\t// http://forums.xilinx.com/t5/Spartan-Family-FPGAs/Spartan6-DCM-CLKGEN-does-PROGCLK-have-a-maximum-period-minimum/td-p/175642\n\t\t\t// BUT this can lock up the DCM, positive clock seems more reliable (but it can still lock up for low values of M, eg 2).\n\t\t\t// Added SPEED_MIN to prevent this (and positive clock is correct, after looking at other implementations eg ztex/theseven)\n\t\t\n\t\t\tif ((start || start_d1) && state==0 && speed_in >= SPEED_MIN && speed_in <= SPEED_LIMIT && progclk==1)\t// positive clock\n\t\t\t// if ((start || start_d1) && state==0 && speed_in >= SPEED_MIN && speed_in <= SPEED_LIMIT && progclk==0)\t// negative clock\n\t\t\tbegin\n\t\t\t\tprogen <= 0;\n\t\t\t\tprogdata <= 0;\n\t\t\t\tmval <= speed_in;\n\t\t\t\tdval <= OSC_MHZ;\n\t\t\t\tstate <= 1;\n\t\t\tend\n\t\t\tif (state != 0)\n\t\t\t\tstate <= state + 1'd1;\n\t\t\tcase (state)\t\t// Even values to sync with progclk\n\t\t\t\t// Send D\n\t\t\t\t2: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\t\tprogdata <= 1;\n\t\t\t\tend\n\t\t\t\t4: begin\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t6,8,10,12,14,16,18,20: begin\n\t\t\t\t\tprogdata <= dval[0];\n\t\t\t\t\tdval[6:0] <= dval[7:1];\n\t\t\t\tend\n\t\t\t\t22: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t// Send M\n\t\t\t\t32: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\t\tprogdata <= 1;\n\t\t\t\tend\n\t\t\t\t36,38,40,42,44,46,48,50: begin\n\t\t\t\t\tprogdata <= mval[0];\n\t\t\t\t\tmval[6:0] <= mval[7:1];\n\t\t\t\tend\n\t\t\t\t52: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t// Send GO - NB 1 clock cycle\n\t\t\t\t62: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\tend\n\t\t\t\t64: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\tend\n\t\t\t\t// We should wait on progdone/locked, but just go straight back to idle\n\t\t\t\t254: begin\n\t\t\t\t\tstate <= 0;\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n\tend\nendmodule\n"
  },
  {
    "path": "experimental/LX150-EIGHT-B/ltcminer-dynclock.py",
    "content": "#!/usr/bin/env python\n\n# by teknohog\n\n# Python wrapper for Xilinx Serial Miner\n\n# CONFIGURATION - CHANGE THIS TO YOUR ACCOUNT DETAILS ...\n# Optionally install a Stratum Proxy Server on localhost\nhost = \"mining-foreman.org\"\t# Getwork\n# host = \"localhost\"\t# Stratum Proxy alternative\nuser = \"username.1\"\t\t# Your worker goes here\npassword = \"password\"\t# Worker password, NOT your account password\nhttp_port = \"10341\"\t\t# Getwork port.\n# http_port = \"8332\"\t# Getwork port (stratum)\n\n# CONFIGURATION - CHANGE THIS (eg try COM1, COM2, COM3, COM4 etc)\nserial_port = \"COM4\"\n# serial_port = \"/dev/ttyUSB0\"\t# raspberry pi\n\n# CONFIGURATION - how often to refresh work. 20 seconds is fine, but work is\n# not initially fetched until this timeout expires. Reduce it for debugging\n# and for stratum (2 works fine).\naskrate = 20\t# Getwork\n# askrate = 2\t# Stratum\n\n###############################################################################\n\nfrom jsonrpc import ServiceProxy\nfrom time import ctime, sleep, time\nfrom serial import Serial\nfrom threading import Thread, Event\nfrom Queue import Queue\nimport sys\n\ndynclock = 0\ndynclock_hex = \"0000\"\n\ndef stats(count, starttime):\n\t# BTC 2**32 hashes per share (difficulty 1)\n\t# mhshare = 4294.967296\n\t# LTC 2**32 / 2048 hashes per share (difficulty 32)\n\t# khshare = 2097.152\t# CHECK THIS !!\n\tkhshare = 65.536 * writer.diff\n\n\ts = sum(count)\n\ttdelta = time() - starttime\n\trate = s * khshare / tdelta\n\n\t# This is only a rough estimate of the true hash rate,\n\t# particularly when the number of events is low. However, since\n\t# the events follow a Poisson distribution, we can estimate the\n\t# standard deviation (sqrt(n) for n events). Thus we get some idea\n\t# on how rough an estimate this is.\n\n\t# s should always be positive when this function is called, but\n\t# checking for robustness anyway\n\tif s > 0:\n\t\tstddev = rate / s**0.5\n\telse:\n\t\tstddev = 0\n\n\treturn \"[%i accepted, %i failed, %.2f +/- %.2f khash/s]\" % (count[0], count[1], rate, stddev)\n\nclass Reader(Thread):\n\tdef __init__(self):\n\t\tThread.__init__(self)\n\n\t\tself.daemon = True\n\n\t\t# flush the input buffer\n\t\tser.read(1000)\n\n\tdef run(self):\n\t\twhile True:\n\t\t\tnonce = ser.read(4)\n\n\t\t\tif len(nonce) == 4:\n\t\t\t\t# Keep this order, because writer.block will be\n\t\t\t\t# updated due to the golden event.\n\t\t\t\tsubmitter = Submitter(writer.block, nonce)\n\t\t\t\tsubmitter.start()\n\t\t\t\tgolden.set()\n\n\nclass Writer(Thread):\n\tdef __init__(self,dynclock_hex):\n\t\tThread.__init__(self)\n\n\t\t# Keep something sensible available while waiting for the\n\t\t# first getwork\n\t\tself.block = \"0\" * 256\n\t\t# self.target = \"f\" * 56 + \"ff070000\"\t\t# diff=32\n\t\tself.target = \"f\" * 56 + \"ff7f0000\"\t\t\t# diff=2\n\t\tself.diff = 2.0\t# NB This is updated from target (default 2 is safer than 32 to avoid losing shares)\n\t\tself.dynclock_hex = dynclock_hex\n\n\t\tself.daemon = True\n\n\tdef run(self):\n\t\twhile True:\n\t\t\ttry:\n\t\t\t\twork = bitcoin.getwork()\n\t\t\t\tself.block = work['data']\n\t\t\t\tself.target = work['target']\n\t\t\texcept:\n\t\t\t\tprint(\"RPC getwork error\")\n\t\t\t\t# In this case, keep crunching with the old data. It will get \n\t\t\t\t# stale at some point, but it's better than doing nothing.\n\n\t\t\t# print(\"block \" + self.block + \" target \" + self.target)\t# DEBUG\n\n\t\t\tsdiff = self.target.decode('hex')[31:27:-1]\n\t\t\tintTarget = int(sdiff.encode('hex'), 16)\n\t\t\tif (intTarget < 1):\n\t\t\t\tprint \"WARNING zero target, defaulting to diff=2\", intTarget\n\t\t\t\tprint \"target\", self.target\n\t\t\t\tprint(\"sdiff\", sdiff)\t# NB Need brackets here else prints binary\n\t\t\t\tself.target = \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000\"\n\t\t\telse:\n\t\t\t\tnewdiff = 65536.0 / (intTarget+1)\n\t\t\t\tif (self.diff != newdiff):\n\t\t\t\t\tprint \"New target diff =\", newdiff\n\t\t\t\tself.diff = newdiff\n\n\t\t\t# Replace MSB 16 bits of target with clock (NB its reversed)\n\t\t\tself.target = self.target[0:60] + self.dynclock_hex\n\t\t\tself.dynclock_hex = \"0000\"\t# Once only\n\t\t\t\n\t\t\tprint(\"Sending data to FPGA\")\t# DEBUG\n\n\t\t\t# for litecoin send 80 bytes of the 128 byte data plus 4 bytes of 32 byte target\n\t\t\tpayload = self.target.decode('hex')[31:27:-1] + self.block.decode('hex')[79::-1]\n\t\t\t\n\t\t\t# TEST HASH, this should match on nonce 0000318f\n\t\t\t# NB The pool will REJECT this share as it did not send the data...\n\t\t\t# UNCOMMENT the following two lines for testing...\n\t\t\t# test_payload =\"000000014eb4577c82473a069ca0e95703254da62e94d1902ab6f0eae8b1e718565775af20c9ba6ced48fc9915ef01c54da2200090801b2d2afc406264d491c7dfc7b0b251e91f141b44717e00310000ff070000\"\n\t\t\t# payload = test_payload.decode('hex')[::-1]\n\n\t\t\tprint(\"Payload \" + payload.encode('hex_codec'))\t# DEBUG\n\t\t\t\n\t\t\tser.write(payload)\n\t\t\t\n\t\t\tresult = golden.wait(askrate)\n\n\t\t\tif result:\n\t\t\t\tgolden.clear()\n\nclass Submitter(Thread):\n\tdef __init__(self, block, nonce):\n\t\tThread.__init__(self)\n\n\t\tself.block = block\n\t\tself.nonce = nonce\n\n\tdef run(self):\n\t\t# This thread will be created upon every submit, as they may\n\t\t# come in sooner than the submits finish.\n\n\t\t# print(\"Block found on \" + ctime())\n\t\tprint(\"Share found on \" + ctime() + \" nonce \" + self.nonce.encode('hex_codec'))\n\t\t\n\t\thrnonce = self.nonce[::-1].encode('hex')\n\n\t\tdata = self.block[:152] + hrnonce + self.block[160:]\n\n\t\ttry:\n\t\t\tresult = bitcoin.getwork(data)\n\t\t\tprint(\"Upstream result: \" + str(result))\n\t\texcept:\n\t\t\tprint(\"RPC send error\")\n\t\t\t# a sensible boolean for stats\n\t\t\tresult = False\n\n\t\tresults_queue.put(result)\n\nclass Display_stats(Thread):\n\tdef __init__(self):\n\t\tThread.__init__(self)\n\n\t\tself.count = [0, 0]\n\t\tself.starttime = time()\n\t\tself.daemon = True\n\n\t\tprint(\"Miner started on \" + ctime())\n\n\tdef run(self):\n\t\twhile True:\n\t\t\tresult = results_queue.get()\n\t\t\t\n\t\t\tif result:\n\t\t\t\tself.count[0] += 1\n\t\t\telse:\n\t\t\t\tself.count[1] += 1\n\t\t\t\t\n\t\t\tprint(stats(self.count, self.starttime))\n\t\t\t\t\n\t\t\tresults_queue.task_done()\n\n# ======= main =======\n\n# Process command line\n\nif (len(sys.argv) > 2):\n\tprint \"ERROR too many command line arguments\"\n\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\tquit()\n\nif (len(sys.argv) == 1):\n\tprint \"WARNING no clockfreq supplied, not setting freq\"\nelse:\n\t# TODO ought to check the value is a valid integer\n\ttry:\n\t\tdynclock = int(sys.argv[1])\n\texcept:\n\t\tprint \"ERROR parsing clock frequency on command line, needs to be an integer\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tif (dynclock==0):\n\t\tprint \"ERROR parsing clock frequency on command line, cannot be zero\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tif (dynclock>254):\t# Its 254 since onescomplement(255) is zero, which is not allowed\n\t\tprint \"ERROR parsing clock frequency on command line, max 254\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tif (dynclock<25):\n\t\tprint \"ERROR use at least 25 for clock (the DCM can lock up for low values)\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tdynclock_hex = \"{0:04x}\".format((255-dynclock)*256+dynclock)\t# both value and ones-complement\n\tprint \"INFO will set clock to\", dynclock, \"MHz hex\", dynclock_hex\n\ngolden = Event()\n\nurl = 'http://' + user + ':' + password + '@' + host + ':' + http_port\n\nbitcoin = ServiceProxy(url)\n\nresults_queue = Queue()\n\n# default is 8 bit no parity which is fine ...\n# http://pyserial.sourceforge.net/shortintro.html#opening-serial-ports\n\nser = Serial(serial_port, 115200, timeout=askrate)\n\nreader = Reader()\nwriter = Writer(dynclock_hex)\ndisp = Display_stats()\n\nreader.start()\nwriter.start()\ndisp.start()\n\ntry:\n\twhile True:\n\t\t# Threads are generally hard to interrupt. So they are left\n\t\t# running as daemons, and we do something simple here that can\n\t\t# be easily terminated to bring down the entire script.\n\t\tsleep(10000)\nexcept KeyboardInterrupt:\n\tprint(\"Terminated\")\n\n"
  },
  {
    "path": "experimental/LX150-EIGHT-B/ltcminer-test-dynclock.py",
    "content": "#!/usr/bin/env python\n\n# by teknohog\n\n# Python wrapper for Xilinx Serial Miner\n\n# Host/user configuration is NOT USED in ltctestmode.py ...\n# host = \"localhost\"\t# Stratum Proxy alternative\n# user = \"username.1\"\t# Your worker goes here\n# password = \"password\"\t# Worker password, NOT your account password\n# http_port = \"8332\"\t# Getwork port (stratum)\n\n# CONFIGURATION - CHANGE THIS (eg try COM1, COM2, COM3, COM4 etc)\nserial_port = \"COM4\"\n# serial_port = \"/dev/ttyUSB0\"\t# raspberry pi\n\n# CONFIGURATION - how often to refresh work - reduced for test\naskrate = 2\n\n###############################################################################\n\nfrom jsonrpc import ServiceProxy\nfrom time import ctime, sleep, time\nfrom serial import Serial\nfrom threading import Thread, Event\nfrom Queue import Queue\nimport sys\n\ndynclock = 0\ndynclock_hex = \"0000\"\n\ndef stats(count, starttime):\n\t# BTC 2**32 hashes per share (difficulty 1)\n\t# mhshare = 4294.967296\n\t# LTC 2**32 / 2048 hashes per share (difficulty 32)\n\t# khshare = 2097.152\t# CHECK THIS !!\n\tkhshare = 65.536 * writer.diff\n\n\ts = sum(count)\n\ttdelta = time() - starttime\n\trate = s * khshare / tdelta\n\n\t# This is only a rough estimate of the true hash rate,\n\t# particularly when the number of events is low. However, since\n\t# the events follow a Poisson distribution, we can estimate the\n\t# standard deviation (sqrt(n) for n events). Thus we get some idea\n\t# on how rough an estimate this is.\n\n\t# s should always be positive when this function is called, but\n\t# checking for robustness anyway\n\tif s > 0:\n\t\tstddev = rate / s**0.5\n\telse:\n\t\tstddev = 0\n\n\treturn \"[%i accepted, %i failed, %.2f +/- %.2f khash/s]\" % (count[0], count[1], rate, stddev)\n\nclass Reader(Thread):\n\tdef __init__(self):\n\t\tThread.__init__(self)\n\n\t\tself.daemon = True\n\n\t\t# flush the input buffer\n\t\tser.read(1000)\n\n\tdef run(self):\n\t\twhile True:\n\t\t\tnonce = ser.read(4)\n\n\t\t\tif len(nonce) == 4:\n\t\t\t\t# Keep this order, because writer.block will be\n\t\t\t\t# updated due to the golden event.\n\t\t\t\tsubmitter = Submitter(writer.block, nonce)\n\t\t\t\tsubmitter.start()\n\t\t\t\tgolden.set()\n\n\nclass Writer(Thread):\n\tdef __init__(self,dynclock_hex):\n\t\tThread.__init__(self)\n\n\t\t# Keep something sensible available while waiting for the\n\t\t# first getwork\n\t\tself.block = \"0\" * 256\n\t\tself.target = \"f\" * 56 + \"ff070000\"\t\t# diff=32 for testmode\n\t\tself.diff = 32\t# testmode\n\t\tself.dynclock_hex = dynclock_hex\n\n\t\tself.daemon = True\n\t\tself.go = True\n\t\tself.infile = open(\"../../scripts/test_data.txt\",\"r\")\n\t\tself.nonce = 0\n\t\tself.nonce_tested = 0\n\t\tself.nonce_ok = 0\n\t\tself.nonce_fail = 0\n\n\tdef run(self):\n\t\twhile self.go:\n\t\t\ttry:\n\t\t\t\t# work = bitcoin.getwork()\n\t\t\t\t# self.block = work['data']\n\t\t\t\t# self.target = work['target']\n\t\t\t\tprint \"Tested\", self.nonce_tested, \" passed\", self.nonce_ok, \" fail\", self.nonce_fail, \" unmatched\", self.nonce_tested - self.nonce_ok - self.nonce_fail\n\t\t\t\tself.line = self.infile.readline()\n\t\t\t\tif (len(self.line) != 257):\n\t\t\t\t\tprint \"EOF on test data\"\t# Or its an error, but let's not be worrysome\n\n\t\t\t\t\t# quit()\t\t# Except it doesn't ...\n\t\t\t\t\tself.go = False\t# Terminating threads is a bit tricksy\n\t\t\t\t\tbreak\n\t\t\t\tself.nonce_tested = self.nonce_tested + 1\n\t\t\t\tself.block = self.line.rstrip()\n\t\t\t\t\n\t\t\t\t# Hard-code a diff=32 target for test work\n\t\t\t\t# Replace MSB 16 bits of target with clock (NB its reversed)\n\t\t\t\tself.target = \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07\" + self.dynclock_hex\n\t\t\t\tself.dynclock_hex = \"0000\"\t# Once only\n\t\t\t\t\n\t\t\t\t# print(\"block old \" + self.block)\n\t\t\t\t# We need to subtract a few from the nonces in order to match (why?)\n\t\t\t\tnonce_bin = self.block.decode('hex')[79:75:-1]\n\t\t\t\tself.nonce = int(nonce_bin.encode('hex'), 16)\n\t\t\t\t# print \"nonce old =\", self.nonce\n\t\t\t\tnonce_new = self.nonce - 50\n\t\t\t\tif (nonce_new < 0):\n\t\t\t\t\tnonce_new = 0\n\t\t\t\t# print \"nonce new =\", nonce_new\n\t\t\t\tnonce_hex = \"{0:08x}\".format(nonce_new)\n\t\t\t\t# print \"encoded = \", nonce_hex\n\t\t\t\tnonce_hex_rev = nonce_hex[6:8]+nonce_hex[4:6]+nonce_hex[2:4]+nonce_hex[0:2]\n\t\t\t\t# print \"reversed = \", nonce_hex_rev\n\t\t\t\tself.block = self.block[0:152]+nonce_hex_rev+self.block[160:]\n\t\t\t\t# print(\"block new \" + self.block)\n\t\t\texcept:\n\t\t\t\tprint(\"RPC getwork error\")\n\t\t\t\t# In this case, keep crunching with the old data. It will get \n\t\t\t\t# stale at some point, but it's better than doing nothing.\n\n\t\t\t# print(\"block \" + self.block + \" target \" + self.target)\t# DEBUG\n\n\t\t\tsdiff = self.target.decode('hex')[31:27:-1]\n\t\t\tintTarget = int(sdiff.encode('hex'), 16)\n\t\t\tif (intTarget < 1):\n\t\t\t\tprint \"WARNING zero target\", intTarget\n\t\t\t\tprint \"target\", self.target\n\t\t\t\tprint(\"sdiff\", sdiff)\t# NB Need brackets here else prints binary\n\t\t\t\tself.target = \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000\"\n\t\t\telse:\n\t\t\t\tnewdiff = 65536 / intTarget\n\t\t\t\tif (self.diff != newdiff):\n\t\t\t\t\tprint \"New target diff =\", newdiff\n\t\t\t\tself.diff = newdiff\n\n\t\t\t# print(\"Sending data to FPGA\")\t# DEBUG\n\n\t\t\t# for litecoin send 80 bytes of the 128 byte data plus 4 bytes of 32 byte target\n\t\t\tpayload = self.target.decode('hex')[31:27:-1] + self.block.decode('hex')[79::-1]\n\t\t\t\n\t\t\t# TEST HASH, this should match on nonce 0000318f\n\t\t\t# NB The pool will REJECT this share as it did not send the data...\n\t\t\t# UNCOMMENT the following two lines for testing...\n\t\t\t# test_payload =\"000000014eb4577c82473a069ca0e95703254da62e94d1902ab6f0eae8b1e718565775af20c9ba6ced48fc9915ef01c54da2200090801b2d2afc406264d491c7dfc7b0b251e91f141b44717e00310000ff070000\"\n\t\t\t# payload = test_payload.decode('hex')[::-1]\n\n\t\t\t# This is probably best commented out unless debugging ...\n\t\t\tprint(\"Test \" + payload.encode('hex_codec'))\t# DEBUG\n\t\t\t\n\t\t\tser.write(payload)\n\t\t\t\n\t\t\tresult = golden.wait(askrate)\n\n\t\t\tif result:\n\t\t\t\tgolden.clear()\n\nclass Submitter(Thread):\n\tdef __init__(self, block, nonce):\n\t\tThread.__init__(self)\n\n\t\tself.block = block\n\t\tself.nonce = nonce\n\n\tdef run(self):\n\t\t# This thread will be created upon every submit, as they may\n\t\t# come in sooner than the submits finish.\n\n\t\t# print(\"Block found on \" + ctime())\n\t\tprint(\"Share found on \" + ctime() + \" nonce \" + self.nonce.encode('hex_codec'))\n\t\tif (int(self.nonce.encode('hex_codec'),16) != writer.nonce):\n\t\t\tprint \"... ERROR expected nonce\", hex(writer.nonce)\n\t\t\twriter.nonce_fail = writer.nonce_fail + 1\n\t\telse:\n\t\t\tprint \"... CORRECT\"\n\t\t\twriter.nonce_ok = writer.nonce_ok + 1\n\t\t\n\t\thrnonce = self.nonce[::-1].encode('hex')\n\n\t\tdata = self.block[:152] + hrnonce + self.block[160:]\n\n\t\ttry:\n\t\t\t# result = bitcoin.getwork(data)\n\t\t\tresult = False\n\t\t\t# print(\"Upstream result: \" + str(result))\t# Pointless in test mode\n\t\texcept:\n\t\t\tprint(\"RPC send error\")\n\t\t\t# a sensible boolean for stats\n\t\t\tresult = False\n\n\t\tresults_queue.put(result)\n\nclass Display_stats(Thread):\n\tdef __init__(self):\n\t\tThread.__init__(self)\n\n\t\tself.count = [0, 0]\n\t\tself.starttime = time()\n\t\tself.daemon = True\n\n\t\tprint(\"Miner started on \" + ctime())\n\n\tdef run(self):\n\t\twhile True:\n\t\t\tresult = results_queue.get()\n\t\t\t\n\t\t\tif result:\n\t\t\t\tself.count[0] += 1\n\t\t\telse:\n\t\t\t\tself.count[1] += 1\n\t\t\t\t\n\t\t\t# print(stats(self.count, self.starttime)) \t# Pointless in test mode\n\t\t\t\t\n\t\t\tresults_queue.task_done()\n\n# ======= main =======\n\n# Process command line\n\nif (len(sys.argv) > 2):\n\tprint \"ERROR too many command line arguments\"\n\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\tquit()\n\nif (len(sys.argv) == 1):\n\tprint \"WARNING no clockfreq supplied, not setting freq\"\nelse:\n\t# TODO ought to check the value is a valid integer\n\ttry:\n\t\tdynclock = int(sys.argv[1])\n\texcept:\n\t\tprint \"ERROR parsing clock frequency on command line, needs to be an integer\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tif (dynclock==0):\n\t\tprint \"ERROR parsing clock frequency on command line, cannot be zero\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tif (dynclock>254):\t# Its 254 since onescomplement(255) is zero, which is not allowed\n\t\tprint \"ERROR parsing clock frequency on command line, max 254\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tif (dynclock<25):\n\t\tprint \"ERROR use at least 25 for clock (the DCM can lock up for low values)\"\n\t\tprint \"usage:\", sys.argv[0], \"clockfreq\"\n\t\tquit()\n\tdynclock_hex = \"{0:04x}\".format((255-dynclock)*256+dynclock)\t# both value and ones-complement\n\tprint \"INFO will set clock to\", dynclock, \"MHz hex\", dynclock_hex\n\ngolden = Event()\n\n# url = 'http://' + user + ':' + password + '@' + host + ':' + http_port\n\n# bitcoin = ServiceProxy(url)\n\nresults_queue = Queue()\n\n# default is 8 bit no parity which is fine ...\n# http://pyserial.sourceforge.net/shortintro.html#opening-serial-ports\n\nser = Serial(serial_port, 115200, timeout=askrate)\n\nreader = Reader()\nwriter = Writer(dynclock_hex)\ndisp = Display_stats()\n\nreader.start()\nwriter.start()\ndisp.start()\n\ntry:\n\twhile writer.go:\n\t\t# Threads are generally hard to interrupt. So they are left\n\t\t# running as daemons, and we do something simple here that can\n\t\t# be easily terminated to bring down the entire script.\n\t\tsleep(1)\nexcept KeyboardInterrupt:\n\tprint(\"Terminated\")\n"
  },
  {
    "path": "experimental/LX150-EIGHT-B/ltcminer_icarus.ucf",
    "content": "# Based on https://github.com/ngzhang/Icarus/blob/master/FPGA_project/Src/fpgaminer_top.ucf\n\nNET \"hash_clk\" TNM_NET = \"hash_clk\";\nNET \"pbkdf_clk\" TNM_NET = \"pbkdf_clk\";\nNET \"uart_clk\" TNM_NET = \"uart_clk\";\n\n# 75MHz hash_clk (it may route better specifying a slightly slower clock)\nTIMESPEC TS_hash_clk = PERIOD \"hash_clk\" 75 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\n# 50MHz pbkdf_clk\nTIMESPEC TS_pbkdf_clk = PERIOD \"pbkdf_clk\" 50 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\n# 12.5MHz uart_clk\nTIMESPEC TS_uart_clk = PERIOD \"uart_clk\" 12.5 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\nNET \"osc_clk\" LOC = J1 | IOSTANDARD = LVCMOS33;\n\n# serial port receive & transmit\nNET \"RxD\" LOC = D1 | IOSTANDARD = LVCMOS33;\nNET \"TxD\" LOC = B1 | IOSTANDARD = LVCMOS33;\n\n# TTL level serial port: ja3 = rxd, ja2 = txd\nNET \"extminer_txd[0]\" LOC = D22 | IOSTANDARD = LVCMOS33;\nNET \"extminer_rxd[0]\" LOC = B22 | IOSTANDARD = LVCMOS33;\n\nNET \"led[0]\" LOC = A18 | IOSTANDARD = LVCMOS33;\nNET \"led[1]\" LOC = B18 | IOSTANDARD = LVCMOS33;\nNET \"led[2]\" LOC = A17 | IOSTANDARD = LVCMOS33;\nNET \"led[3]\" LOC = A16 | IOSTANDARD = LVCMOS33;\n\nNET \"dip[0]\" LOC = A4 | IOSTANDARD = LVCMOS33;\nNET \"dip[1]\" LOC = D6 | IOSTANDARD = LVCMOS33;\nNET \"dip[2]\" LOC = C6 | IOSTANDARD = LVCMOS33;\nNET \"dip[3]\" LOC = C8 | IOSTANDARD = LVCMOS33;\n\nNET \"TMP_SCL\" LOC = C1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_SDA\" LOC = E1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_ALERT\" LOC = C3 | IOSTANDARD = LVCMOS33 | PULLUP;\n"
  },
  {
    "path": "experimental/LX150-EIGHT-B/ltcminer_icarus.v",
    "content": "/* ltcminer_icarus.v copyright kramble 2013\n * Based on https://github.com/teknohog/Open-Source-FPGA-Bitcoin-Miner/tree/master/projects/Xilinx_cluster_cgminer\n * Hub code for a cluster of miners using async links\n * by teknohog\n */\n\n`include \"../../source/sha-256-functions.v\"\n`include \"../../source/sha256_transform.v\"\n// `include \"../../ICARUS-LX150/xilinx_pll.v\"\t// Only needed if not USE_DYN_PLL\n`include \"../../ICARUS-LX150/uart_receiver.v\"\n`include \"../../ICARUS-LX150/uart_transmitter.v\"\n`include \"../../ICARUS-LX150/serial.v\"\n`include \"../../ICARUS-LX150/serial_hub.v\"\n`include \"../../ICARUS-LX150/hub_core.v\"\n`include \"../../ICARUS-LX150/pwm_fade.v\"\n\nmodule ltcminer_icarus (osc_clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n// NB SPEED_MHZ resolution is 5MHz steps to keep pll divide ratio sensible. Change the divider in xilinx_pll.v if you\n// want other steps (1MHz is not sensible as it requires divide 100 which is not in the allowed range 1..32 for DCM_SP)\n// New dyn_pll has 1MHz resolution and can be changed by sending a specific getwork packet (uses top bytes of target)\n\n`define USE_DYN_PLL\t\t// Enable new dyn_pll\n\n`ifdef SPEED_MHZ\n\tparameter SPEED_MHZ = `SPEED_MHZ;\n`else\n\tparameter SPEED_MHZ = 50;\t\t\t\t\t\t// Default to slow, use dynamic config to ramp up in realtime\n`endif\n\n`ifdef SPEED_LIMIT\n\tparameter SPEED_LIMIT = `SPEED_LIMIT;\t\t\t// Fastest speed accepted by dyn_pll config\n`else\n\tparameter SPEED_LIMIT = 150;\t\t\t\t\t// Deliberately conservative, increase at own risk\n`endif\n\n`ifdef SERIAL_CLK\n\tparameter comm_clk_frequency = `SERIAL_CLK;\n`else\n\tparameter comm_clk_frequency = 12_500_000;\t\t// 100MHz divide 8\n`endif\n\n`ifdef BAUD_RATE\n\tparameter BAUD_RATE = `BAUD_RATE;\n`else\n\tparameter BAUD_RATE = 115_200;\n`endif\n\n// kramble - nonce distribution is crude using top 4 bits of nonce so max LOCAL_MINERS = 8\n// teknohog's was more sophisticated, but requires modification of hashcore.v\n\n// Miners on the same FPGA with this hub\n`ifdef LOCAL_MINERS\n\tparameter LOCAL_MINERS = `LOCAL_MINERS;\n`else\n\tparameter LOCAL_MINERS = 4;\t\t\t\t\t\t// One to four cores (configures ADDRBITS automatically)\n`endif\n\n`ifdef ADDRBITS\n\tparameter ADDRBITS = `ADDRBITS;\t\t\t\t\t// Override for simulation or a quick ISE build (eg one 10 bit core)\n`else\n\tparameter ADDRBITS = 12 - clog2(LOCAL_MINERS);\t// Automatically selects largest RAM that will fit LX150\n`endif\n\n// kramble - nonce distribution only works for a single external port \n`ifdef EXT_PORTS\n\tparameter EXT_PORTS = `EXT_PORTS;\n`else\n\tparameter EXT_PORTS = 1;\n`endif\n\n\tlocalparam SLAVES = LOCAL_MINERS + EXT_PORTS;\n\n\tinput osc_clk;\n\twire hash_clk, uart_clk, pbkdf_clk;\n\n`ifdef USE_DYN_PLL\n\twire first_dcm_locked, dcm_progclk, dcm_progdata, dcm_progen, dcm_reset, dcm_progdone, dcm_locked;\n\twire [2:1] dcm_status;\n`endif\n\n`ifndef SIM\n\t`ifdef USE_DYN_PLL\n\t\tdyn_pll # (.SPEED_MHZ(SPEED_MHZ)) dyn_pll_blk\n\t\t\t(osc_clk, \n\t\t\tpbkdf_clk, \n\t\t\thash_clk, \n\t\t\tuart_clk,\n\t\t\tfirst_dcm_locked,\n\t\t\tdcm_progclk,\n\t\t\tdcm_progdata,\n\t\t\tdcm_progen,\n\t\t\tdcm_reset,\n\t\t\tdcm_progdone,\n\t\t\tdcm_locked,\n\t\t\tdcm_status);\n\t`else\n\t\tmain_pll # (.SPEED_MHZ(SPEED_MHZ)) pll_blk (.CLKIN_IN(osc_clk), .CLKFX_OUT(hash_clk), .CLKDV_OUT(uart_clk));\n\t\tassign pbkdf_clk = uart_clk;\n\t`endif\n`else\n\tassign hash_clk = osc_clk;\n\tassign uart_clk = osc_clk;\n\tassign pbkdf_clk = osc_clk;\n\t`ifdef USE_DYN_PLL\n\t\tassign first_dcm_locked = 1'b1;\n\t\tassign dcm_locked = 1'b1;\n\t\tassign dcm_status = 8'd0;\n\t`endif\t\n`endif\n\n`ifdef USE_DYN_PLL\n\treg [7:0] dyn_pll_speed = SPEED_MHZ;\n\treg dyn_pll_start = 0;\n\tparameter OSC_MHZ = 100;\t\t// Clock oscillator (used for divider ratio)\n\tdyn_pll_ctrl # (.SPEED_MHZ(SPEED_MHZ), .SPEED_LIMIT(SPEED_LIMIT), .OSC_MHZ(OSC_MHZ)) dyn_pll_ctrl_blk\n\t\t(uart_clk,\t\t\t// NB uses uart_clk as its just osc/8 and should always be valid\n\t\tfirst_dcm_locked,\t// ... but we check it anyway\n\t\tdyn_pll_speed,\n\t\tdyn_pll_start,\n\t\tdcm_progclk,\n\t\tdcm_progdata,\n\t\tdcm_progen,\n\t\tdcm_reset,\n\t\tdcm_locked,\n\t\tdcm_status);\n`endif\n      \n\tinput TMP_SCL, TMP_SDA, TMP_ALERT;\t// Unused but set to PULLUP so as to avoid turning on the HOT LED\n\t\t\t\t\t\t\t\t\t\t// TODO implement I2C protocol to talk to temperature sensor chip (TMP101?)\n\t\t\t\t\t\t\t\t\t\t// and drive FAN speed control output.\n\n\tinput [3:0]dip;\n\twire reset, nonce_chip;\n\tassign reset = dip[0];\t\t\t// Not used\n\tassign nonce_chip = dip[1];\t\t// Distinguishes between the two Icarus FPGA's\n\n\t// Work distribution is simply copying to all miners, so no logic\n\t// needed there, simply copy the RxD.\n\tinput\tRxD;\n\toutput\tTxD;\n\n\t// Results from the input buffers (in serial_hub.v) of each slave\n\twire [SLAVES*32-1:0]\tslave_nonces;\n\twire [SLAVES-1:0]\t\tnew_nonces;\n\n\t// Using the same transmission code as individual miners from serial.v\n\twire\t\tserial_send;\n\twire\t\tserial_busy;\n\twire [31:0]\tgolden_nonce;\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) sertx (.clk(uart_clk), .TxD(TxD), .send(serial_send), .busy(serial_busy), .word(golden_nonce));\n\n\thub_core #(.SLAVES(SLAVES)) hc (.uart_clk(uart_clk), .new_nonces(new_nonces), .golden_nonce(golden_nonce), .serial_send(serial_send), .serial_busy(serial_busy), .slave_nonces(slave_nonces));\n\n\t// Common workdata input for local miners\n\twire [255:0]\tdata1, data2;\n\twire [127:0]\tdata3;\n\twire [31:0]\t\ttarget;\n\treg  [31:0]\t\ttargetreg = 32'h000007ff;\t// Start at sane value (overwritten by serial_receive)\n\twire\t\t\trx_done;\t\t// Signals hashcore to reset the nonce\n\t\t\t\t\t\t\t\t\t// NB in my implementation, it loads the nonce from data3 which should be fine as\n\t\t\t\t\t\t\t\t\t// this should be zero, but also supports testing using non-zero nonces.\n\n\t// Synchronise across clock domains from uart_clk to hash_clk\n\t// This probably looks amateurish (mea maxima culpa, novice verilogger at work), but should be OK\n\treg rx_done_toggle = 1'b0;\t\t// uart_clk domain\n\talways @ (posedge uart_clk)\n\t\trx_done_toggle <= rx_done_toggle ^ rx_done;\n\n\treg rx_done_toggle_d1 = 1'b0;\t// hash_clk domain\n\treg rx_done_toggle_d2 = 1'b0;\n\treg rx_done_toggle_d3 = 1'b0;\n\t\n\twire loadnonce;\n\tassign loadnonce = rx_done_toggle_d3 ^ rx_done_toggle_d2;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\trx_done_toggle_d1 <= rx_done_toggle;\n\t\trx_done_toggle_d2 <= rx_done_toggle_d1;\n\t\trx_done_toggle_d3 <= rx_done_toggle_d2;\n\t\tif (loadnonce)\n\t\t\ttargetreg <= target;\n\tend\n\t// End of clock domain sync\n\n\twire [31:0] mod_target;\n\n`ifdef USE_DYN_PLL\n\t// Top byte of target is clock multiplier, 2nd byte is validation (one's complement of clock multiplier)\n\t// These bytes are always zero in normal getwork, so we now hard code in mod_target and use them to set clock speed.\n\t// NB The pll controller is in uart_clk domain so use serial_receive signals directly\n\t// wire [7:0]invtarg;\t\t\t\t\t// Just checking the syntax in simulator, DELETE\n\t// assign invtarg = ~target[24:16];\n\talways @ (posedge uart_clk)\n\tbegin\n\t\tdyn_pll_start <= 0;\n\t\t// A sanity check to reduce the risk of speed being set to garbage\n\t\t// Top byte of target is speed, second byte MUST be its inverse, and neither must be zero (which also rules out all ones)\n\t\tif (rx_done && target[31:24] != dyn_pll_speed && target[31:24] != 0 && target[23:16] != 0 && target[31:24] == ~target[23:16])\n\t\t// if (rx_done && target[31:24] != dyn_pll_speed && target[31:24] != 0)\t// Simpler version for DEBUG, does no verification\n\t\tbegin\n\t\t\tdyn_pll_speed <= target[31:24];\n\t\t\tdyn_pll_start <= 1;\n\t\tend\n\tend\n\tassign mod_target = { 16'd0, targetreg[15:0] };\t// Ignore top two bytes\n`else\n\t// Its better to always hard-wire the 16 MSB to zero ... if comms noise sets these bits it completely de-syncs,\n\t// generating a continuous stream of golden_nonces overwhelming the python driver which can't then reset the target.\n\t// assign mod_target = targetreg;\t\t\t\t// Original 32 bit target\n\tassign mod_target = { 16'd0, targetreg[15:0] };\t// Ignore top two bytes\n`endif\n\t\n\tserial_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) serrx (.clk(uart_clk), .RxD(RxD), .data1(data1),\n\t\t\t\t\t\t.data2(data2), .data3(data3), .target(target), .rx_done(rx_done));\n\n\t// Local miners now directly connected\n\tgenerate\n\t\tgenvar i;\n\t\tfor (i = 0; i < LOCAL_MINERS; i = i + 1)\n\t\t// begin: for_local_miners ... too verbose, so...\n\t\tbegin: miners\n\t\t\twire [31:0] nonce_out;\t// Not used\n\t\t\twire [2:0] nonce_core = i;\n\t\t\twire gn_match;\n\t\t\t\n\t\t\twire salsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift;\n\n\t\t\t// Currently one pbkdfengine per salsaengine - TODO share the pbkdfengine for several salsaengines\n\t\t\tpbkdfengine P (.hash_clk(hash_clk), .pbkdf_clk(pbkdf_clk), .data1(data1), .data2(data2), .data3(data3), .target(mod_target),\n\t\t\t\t.nonce_msb({nonce_chip, nonce_core}), .nonce_out(nonce_out), .golden_nonce_out(slave_nonces[i*32+31:i*32]),\n\t\t\t\t.golden_nonce_match(gn_match), .loadnonce(loadnonce),\n\t\t\t\t.salsa_din(salsa_din), .salsa_dout(salsa_dout), .salsa_busy(salsa_busy), .salsa_result(salsa_result),\n\t\t\t\t.salsa_reset(salsa_reset), .salsa_start(salsa_start), .salsa_shift(salsa_shift));\n\n\t\t\tsalsaengine #(.ADDRBITS(ADDRBITS)) S (.hash_clk(hash_clk), .reset(salsa_reset), .din(salsa_din), .dout(salsa_dout),\n\t\t\t\t.shift(salsa_shift), .start(salsa_start), .busy(salsa_busy), .result(salsa_result) );\n\t\t\t\t\t\n\t\t\t// Synchronise across clock domains from pbkdf_clk to uart_clk for: assign new_nonces[i] = gn_match;\n\t\t\treg gn_match_toggle = 1'b0;\t\t// hash_clk domain\n\t\t\talways @ (posedge pbkdf_clk)\n\t\t\t\tgn_match_toggle <= gn_match_toggle ^ gn_match;\n\n\t\t\treg gn_match_toggle_d1 = 1'b0;\t// uart_clk domain\n\t\t\treg gn_match_toggle_d2 = 1'b0;\n\t\t\treg gn_match_toggle_d3 = 1'b0;\n\n\t\t\tassign new_nonces[i] = gn_match_toggle_d3 ^ gn_match_toggle_d2;\n\n\t\t\talways @ (posedge uart_clk)\n\t\t\tbegin\n\t\t\t\tgn_match_toggle_d1 <= gn_match_toggle;\n\t\t\t\tgn_match_toggle_d2 <= gn_match_toggle_d1;\n\t\t\t\tgn_match_toggle_d3 <= gn_match_toggle_d2;\n\t\t\tend\n\t\t\t// End of clock domain sync\n\t\tend // for\n\tendgenerate\n\n\t// External miner ports, results appended to the same\n\t// slave_nonces/new_nonces as local ones\n\toutput [EXT_PORTS-1:0] extminer_txd;\n\tinput [EXT_PORTS-1:0]  extminer_rxd;\n\tassign extminer_txd = {EXT_PORTS{RxD}};\n\n\tgenerate\n\t\tgenvar j;\n\t\tfor (j = LOCAL_MINERS; j < SLAVES; j = j + 1)\n\t\t// begin: for_ports ... too verbose, so ...\n\t\tbegin: ports\n\t\t\tslave_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) slrx (.clk(uart_clk), .RxD(extminer_rxd[j-LOCAL_MINERS]), .nonce(slave_nonces[j*32+31:j*32]), .new_nonce(new_nonces[j]));\n\t\tend\n\tendgenerate\n\n\toutput [3:0] led;\n\tassign led[1] = ~RxD;\n\t// assign led[2] = ~TxD;\n\t// assign led[3] = ~ (TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED - held low (the TMP pins are PULLUP, this is a fudge to\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// avoid warning about unused inputs)\n\t\n\tassign led[3] = ~first_dcm_locked | ~dcm_locked | dcm_status[2] | ~(TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED now dcm status\n\n`define FLASHCLOCK\t\t// Gives some feedback as the the actual clock speed\n\n`ifdef FLASHCLOCK\n\treg [26:0] hash_count = 0;\n\treg [3:0] sync_hash_count = 0;\n\talways @ (posedge uart_clk)\n\t\tif (rx_done)\n\t\t\tsync_hash_count[0] <= ~sync_hash_count[0];\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tsync_hash_count[3:1] <= sync_hash_count[2:0];\n\t\thash_count <= hash_count + 1'b1;\n\t\tif (sync_hash_count[3] != sync_hash_count[2])\n\t\t\thash_count <= 0;\n\tend\n\tassign led[2] = hash_count[26];\n`else\n\tassign led[2] = ~TxD;\n`endif\n\n\t// Light up only from locally found nonces, not ext_port results\n\tpwm_fade pf (.clk(uart_clk), .trigger(|new_nonces[LOCAL_MINERS-1:0]), .drive(led[0]));\n   \nendmodule\n"
  },
  {
    "path": "experimental/LX150-EIGHT-B/pbkdfengine.v",
    "content": "/* pbkdfengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`define ICARUS\t\t\t// Comment this out when using the altera virtual_wire interface in ltcminer.v\n\t\n`timescale 1ns/1ps\n\nmodule pbkdfengine\n\t(hash_clk, pbkdf_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce,\n\t\t\tsalsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift);\n\n\tinput hash_clk;\t\t\t// Just drives shift register\n\tinput pbkdf_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\n\toutput [31:0] nonce_out;\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\n\tinput salsa_dout;\n\toutput salsa_din;\n\tinput salsa_busy, salsa_result;\t// NB hash_clk domain\n\toutput salsa_reset;\n\toutput salsa_start;\n\toutput reg salsa_shift = 1'b0;\t// NB hash_clk domain\n\n\treg [3:0]resetcycles = 4'd0;\n\treg reset = 1'b0;\n\tassign salsa_reset = reset;\t\t// Propagate reset to salsaengine\n\n`ifdef WANTCYCLICRESET\t\t\n\treg [23:0]cycresetcount = 24'd0;\n`endif\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\t// Hard code a 15 cycle reset (NB assumes THREADS=8 in salsaengine, else we need more)\n\t\t// NB hash_clk is faster than pbkdf_clk so the salsaengine will actually be initialised well before\n\t\t// this period ends, but keep to 15 for now as simulation uses equal pbkdf and salsa clock speeds.\n\t\tresetcycles <= resetcycles + 1'd1;\n\t\tif (resetcycles == 0)\n\t\t\treset <= 1'b1;\n\t\tif (resetcycles == 15)\n\t\tbegin\n\t\t\treset <= 1'b0;\n\t\t\tresetcycles <= 15;\n\t\tend\n`ifdef WANTCYCLICRESET\t\t\n\t\t// Cyclical reset every 2_500_000 clocks to ensure salsa pipeline does not drift out of sync\n\t\t// This may be unneccessary if we reset every loadnonce\n\t\t// Actually it seems to do more harm than good, so disabled\n\t\tcycresetcount <= cycresetcount + 1'd1;\n\t\tif (cycresetcount == 2_500_000)\t// 10 per second at 25MHz (adjust as neccessary)\n\t\tbegin\n\t\t\tcycresetcount <= 24'd0;\n\t\t\tresetcycles <= 4'd0;\n\t\tend\n`endif\t\t\n\t\t// Reset on loadnonce (the hash results will be junk anyway since data changes, so no loss of shares)\n\t\tif (loadnonce)\n\t\t\tresetcycles <= 4'd0;\n\tend\n\t\n\t`ifndef ICARUS\n\treg [31:0] nonce_previous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\t`endif\n\n\t`ifndef NOMULTICORE\n\t`ifdef SIM\n\t\treg [27:0] nonce_cnt = 28'h318f;\t// Start point for simulation (NB also define SIM in serial.v)\n\t`else\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t`endif\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\tassign nonce_out = nonce;\n\n\treg [31:0] nonce_sr = 32'd0;\t\t// Nonce is shifted to salsaengine for storage/retrieval (hash_clk domain)\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\treg [2:0] nonce_wait = 3'd0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [2:0] blockcnt = 3'd0;\t\t// Takes values 1..5 for block iteration\n\treg [1023:0] Xbuf = 1024'd0;\t// Shared input/output buffer and shift register (hash_clk domain)\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\tassign salsa_din = Xbuf[1023];\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\t\n\t// MixOut is little-endian word format to match scrypt.c so convert back to big-endian\n\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] mix;\n\t\tassign mix = Xbuf[`IDX(i)];\t\t// NB MixOut now shares Xbuf since shifted in/out\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\n\t// Interface control. This should be OK provided the threads remain evenly spaced (hence we reset on loadnonce)\n\t\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\treg Clr_SMixOutRdy = 1'b0;\n\n\treg [3:0]salsa_busy_d;\t\t\t// Sync to pbkdf_clk domain\n\treg [3:0]salsa_result_d;\n\n\twire Clr_SMixInRdy;\n\tassign Clr_SMixInRdy = SMixInRdy_state & salsa_busy_d[2] & ~salsa_busy_d[3];\t\t// Clear on transition to busy\n\t\n\twire Set_SMixOutRdy;\n\tassign Set_SMixOutRdy = ~SMixOutRdy_state & salsa_result_d[2] & ~salsa_result_d[3];\t// Set on transition to result\n\t\n\t// Clock crossing flags for shift register control (span pbkdf_clk, hash_clk domains)\n\treg [3:0]Xbuf_load_request = 1'b0;\n\treg [3:0]shift_request =  1'b0;\n\treg [3:0]shift_acknowledge = 1'b0;\n\t\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tsalsa_busy_d[0] <= salsa_busy;\t\t\t// Sync to pbkdf_clk domain\n\t\tsalsa_busy_d[3:1] <= salsa_busy_d[2:0];\n\t\tsalsa_result_d[0] <= salsa_result;\n\t\tsalsa_result_d[3:1] <= salsa_result_d[2:0];\n\t\t\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\t\t\t\n\t\t// CARE there is a race with Set_SMixInRdy, Clr_SMixOutRdy which are set in the FSM\n\t\t// Need to assert reset for several cycles to ensure consistency (acutally use 15 since salsaengine needs more)\n\t\tif (reset)\n\t\tbegin\t\t\t\t\t\t\t// Reset takes priority\n\t\t\tSMixInRdy_state <= 1'b0;\n\t\t\tSMixOutRdy_state <= 1'b0;\n\t\tend\n\tend\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\tassign salsa_start = SMixInRdy;\n\t\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz)\n\t\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_NONCE=22, S_SHIFT_IN=41, S_SHIFT_OUT=42,\t\t\t\t// Direction relative to salsa unit\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\treg start_output = 0;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\n\t\tshift_acknowledge[3:1] <= shift_acknowledge[2:0];\t// Clock crossing\n\n\t\t`ifdef ICARUS\n\t\tif (loadnonce)\t\t\t\t// Separate clock domains means comparison is unsafe\n\t\t`else\n\t\tif (loadnonce || (nonce_previous_load != data3[127:96]))\n\t\t`endif\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_previous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\t`ifndef ICARUS\n\t\t\tnonce_previous_load <= data3[127:96];\n\t\t\t`endif\n\t\tend\n\t\t\n\t\tif (reset == 1'b1)\n\t\tbegin\n\t\t\tstate <= S_IDLE;\n\t\t\tstart_output <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tif (SMixOutRdy & ~start_output)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\t// Request shifter to start\n\t\t\t\t\t\tstate <= S_SHIFT_OUT;\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (start_output ||\t// Process output\n\t\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'b0;\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\t\tblockcnt <= 3'd1;\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_sr : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\t\t\n\t\t\t\tS_B6: begin\n\t\t\t\t\t\tkhash <= tx_hash;\t\t// Save temporarily (for Xbuf)\n\n\t\t\t\t\t\tXbuf_load_request[0] <= ~Xbuf_load_request[0];\t// NB also loads nonce_sr\n\n\t\t\t\t\t\tif (blockcnt == 3'd5)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tnonce_wait <= 3'd7;\n\t\t\t\t\t\t\tstate <= S_NONCE;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_NONCE: begin\n\t\t\t\t\t\t// Need to delay a few clocks for Xbuf_load_request to complete\n\t\t\t\t\t\tnonce_wait <= nonce_wait - 1'd1;\n\t\t\t\t\t\tif (nonce_wait == 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 1'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 1'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\n\t\t\t\t\t\t\tstate <= S_SHIFT_IN;\n\t\t\t\t\t\tend\n\t\t\t\t\n\t\t\t\tend\n\t\t\t\tS_SHIFT_IN: begin\t\t\t\t\t\t\t// Shifting from PBKDF2_SHA256 to salsa\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tSet_SMixInRdy <= 1'd1;\t\t\t\t// Flag salsa to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_SHIFT_OUT: begin\t\t\t\t\t\t\t// Shifting from salsa to PBKDF2_SHA256\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'd1;\t\t\t\t// Flag self to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_sr;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n\tend\n\n\t// Shift register control - NB hash_clk domain\n\t\n\treg\t[10:0]shift_count = 11'd0;\t// hash_clk domain\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tif (reset)\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b0;\n\t\t\tshift_count <= 11'd0;\n\t\tend\n\n\t\t// Clock crossing logic\n\t\tXbuf_load_request[3:1] <= Xbuf_load_request[2:0];\n\t\tif (Xbuf_load_request[3] != Xbuf_load_request[2])\n\t\tbegin\n\t\t\t// Shift output into X buffer from MSB->LSB\n\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\tXbuf[1023:768] <= khash;\n\n\t\t\tnonce_sr <= nonce;\t// Loaded several times, but of no consequence\n\t\tend\n\t\t\n\t\tshift_request[3:1] <= shift_request[2:0];\n\t\tif (shift_request[3] != shift_request[2])\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b1;\n\t\tend\n\n\t\tif (salsa_shift)\n\t\tbegin\n\t\t\tshift_count <= shift_count + 1'b1;\n\t\t\tXbuf <= { Xbuf[1022:0], nonce_sr[31] };\n\t\t\tnonce_sr <= { nonce_sr[30:0], salsa_dout };\n\t\tend\n\t\t\n\t\tif (shift_count == 1024+32-1)\n\t\tbegin\n\t\t\tshift_acknowledge[0] = ~shift_acknowledge[0];\n\t\t\tshift_count <= 0;\n\t\t\tsalsa_shift <= 0;\n\t\tend\n\tend\n\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(pbkdf_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\nendmodule"
  },
  {
    "path": "experimental/LX150-EIGHT-B/salsa_piped.v",
    "content": "/* salsa_piped.v ... fully registered salsa core (column and row results regs)\n*\n* Copyright (c) 2013 kramble\n* Derived from scrypt.c Copyright 2009 Colin Percival, 2011 ArtForz\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\nmodule salsa (clk, feedback, B, Bx, Bo, X0out, X1out, Xaddr);\n\n// Latency 9 clock cycles (4 col steps + 4 row + 1 sync), hence 4 salsa iterations in 36 cycles\n\ninput clk;\ninput feedback;\ninput [511:0]B;\ninput [511:0]Bx;\noutput [511:0]Bo;\noutput [511:0]X0out;\t// Pipelined B\noutput [511:0]X1out;\t// Pipelined Bx\noutput [9:0]Xaddr;\t\t// Address\n\nwire [511:0]xx;\t\t\t// Initial xor\nwire [511:0]xxd8;\t\t// Delayed 8 cycles\n\nwire [511:0]xr;\t\t\t// Output of salsa core\nreg [511:0]xrd;\t\t\t// Feedback (9th latency step to maintain sync with ram access)\n\nwire [9:0]addr;\t\t\t// Address from salsa\nreg [9:0]xxd7_addr;\n\n// X0/X1 delays ... just to check timing, probably need to use a ram location to reduce routing congestion\n\nreg [511:0]x0d1;\nreg [511:0]x0d2;\nreg [511:0]x0d3;\nreg [511:0]x0d4;\nreg [511:0]x0d5;\nreg [511:0]x0d6;\nreg [511:0]x0d7;\nreg [511:0]x0d8;\n\nreg [511:0]x1d1;\nreg [511:0]x1d2;\nreg [511:0]x1d3;\nreg [511:0]x1d4;\nreg [511:0]x1d5;\nreg [511:0]x1d6;\nreg [511:0]x1d7;\nreg [511:0]x1d8;\n\nassign X0out = x0d8;\nassign X1out = x1d8;\n\nsalsa_core salsa1 (clk, feedback ? xrd : xx, xr, addr);\n\nalways @ (posedge clk)\nbegin\n\txrd <= xr;\n\n\tx0d1 <= B;\n\tx0d2 <= x0d1;\n\tx0d3 <= x0d2;\n\tx0d4 <= x0d3;\n\tx0d5 <= x0d4;\n\tx0d6 <= x0d5;\n\tx0d7 <= x0d6;\n\tx0d8 <= x0d7;\n\t\n\tx1d1 <= Bx;\n\tx1d2 <= x1d1;\n\tx1d3 <= x1d2;\n\tx1d4 <= x1d3;\n\tx1d5 <= x1d4;\n\tx1d6 <= x1d5;\n\tx1d7 <= x1d6;\n\tx1d8 <= x1d7;\n\t\n\txxd7_addr <= x0d6[9:0] ^ x1d6[9:0];\nend\n\t\ngenvar i;\ngenerate\n\tfor (i = 0; i < 16; i = i + 1) begin : XX\n\t\t// Initial XOR. NB this adds to the propagation delay of the first salsa, may want register it.\n\t\tassign xx[`IDX(i)] = B[`IDX(i)] ^ Bx[`IDX(i)];\n\t\tassign xxd8[`IDX(i)] = x0d8[`IDX(i)] ^ x1d8[`IDX(i)];\t\t// Could do one cycle early (in reg) to save an xor delay\n\t\t// Final sum. NB Ouptut is at 8 cycle latency.\n\t\tassign Bo[`IDX(i)] = xxd8[`IDX(i)] + xr[`IDX(i)];\n\tend\nendgenerate\n\nassign Xaddr = xxd7_addr + addr;\n\nendmodule\n\nmodule salsa_core (clk, x, out, addr);\n\ninput clk;\ninput [511:0]x;\noutput [511:0]out;\noutput [9:0]addr;\n\n// This is clunky due to my lack of verilog skills but it works so elegance can come later\n// ... actually its now gotten quite ridiculous, see KLUDGE below\n\n// Aliases for inputs\n\nwire [31:0] x00;\nwire [31:0] x01;\nwire [31:0] x02;\nwire [31:0] x03;\nwire [31:0] x04;\nwire [31:0] x05;\nwire [31:0] x06;\nwire [31:0] x07;\nwire [31:0] x08;\nwire [31:0] x09;\nwire [31:0] x10;\nwire [31:0] x11;\nwire [31:0] x12;\nwire [31:0] x13;\nwire [31:0] x14;\nwire [31:0] x15;\n\nassign x00 = x[`IDX(0)];\nassign x01 = x[`IDX(1)];\nassign x02 = x[`IDX(2)];\nassign x03 = x[`IDX(3)];\nassign x04 = x[`IDX(4)];\nassign x05 = x[`IDX(5)];\nassign x06 = x[`IDX(6)];\nassign x07 = x[`IDX(7)];\nassign x08 = x[`IDX(8)];\nassign x09 = x[`IDX(9)];\nassign x10 = x[`IDX(10)];\nassign x11 = x[`IDX(11)];\nassign x12 = x[`IDX(12)];\nassign x13 = x[`IDX(13)];\nassign x14 = x[`IDX(14)];\nassign x15 = x[`IDX(15)];\n\n// Column & Row Results (yup, I wrote a program to generate these) ...\n// Not all of these are used, but let the synthesizer take care of that for now\n// TODO prune the unused ones, may be important with certain synth settings\n\n// BEGIN KLUDGE\n`include \"sgen.inc\"\t\t\t// .inc so it does not accidentally get compiled separately as .v\n// END KLUDGE\n\nwire [31:0]c00s;\t\t\t// Column sums\nwire [31:0]c01s;\nwire [31:0]c02s;\nwire [31:0]c03s;\nwire [31:0]c04s;\nwire [31:0]c05s;\nwire [31:0]c06s;\nwire [31:0]c07s;\nwire [31:0]c08s;\nwire [31:0]c09s;\nwire [31:0]c10s;\nwire [31:0]c11s;\nwire [31:0]c12s;\nwire [31:0]c13s;\nwire [31:0]c14s;\nwire [31:0]c15s;\n\nwire [31:0]r00s;\t\t\t// Row sums\nwire [31:0]r01s;\nwire [31:0]r02s;\nwire [31:0]r03s;\nwire [31:0]r04s;\nwire [31:0]r05s;\nwire [31:0]r06s;\nwire [31:0]r07s;\nwire [31:0]r08s;\nwire [31:0]r09s;\nwire [31:0]r10s;\nwire [31:0]r11s;\nwire [31:0]r12s;\nwire [31:0]r13s;\nwire [31:0]r14s;\nwire [31:0]r15s;\n\nwire [31:0]r00sx;\n\n/* From scrypt.c\n\n#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))\n\tfor (i = 0; i < 8; i += 2) {\n\t\t// Operate on columns\n\t\tx04 ^= R(x00+x12, 7);\tx09 ^= R(x05+x01, 7);\tx14 ^= R(x10+x06, 7);\tx03 ^= R(x15+x11, 7);\n\t\tx08 ^= R(x04+x00, 9);\tx13 ^= R(x09+x05, 9);\tx02 ^= R(x14+x10, 9);\tx07 ^= R(x03+x15, 9);\n\t\tx12 ^= R(x08+x04,13);\tx01 ^= R(x13+x09,13);\tx06 ^= R(x02+x14,13);\tx11 ^= R(x07+x03,13);\n\t\tx00 ^= R(x12+x08,18);\tx05 ^= R(x01+x13,18);\tx10 ^= R(x06+x02,18);\tx15 ^= R(x11+x07,18);\n\n\t\t// Operate on rows\n\t\tx01 ^= R(x00+x03, 7);\tx06 ^= R(x05+x04, 7);\tx11 ^= R(x10+x09, 7);\tx12 ^= R(x15+x14, 7);\n\t\tx02 ^= R(x01+x00, 9);\tx07 ^= R(x06+x05, 9);\tx08 ^= R(x11+x10, 9);\tx13 ^= R(x12+x15, 9);\n\t\tx03 ^= R(x02+x01,13);\tx04 ^= R(x07+x06,13);\tx09 ^= R(x08+x11,13);\tx14 ^= R(x13+x12,13);\n\t\tx00 ^= R(x03+x02,18);\tx05 ^= R(x04+x07,18);\tx10 ^= R(x09+x08,18);\tx15 ^= R(x14+x13,18);\n\t}\n*/\n\n// cols\n\nassign c04s = x00 + x12;\nassign c09s = x05 + x01;\nassign c14s = x10 + x06;\nassign c03s = x15 + x11;\n\nassign c08s = c04 + x00d1;\nassign c13s = c09 + x05d1;\nassign c02s = c14 + x10d1;\nassign c07s = c03 + x15d1;\n\nassign c12s = c08 + c04d1;\nassign c01s = c13 + c09d1;\nassign c06s = c02 + c14d1;\nassign c11s = c07 + c03d1;\n\nassign c00s = c12 + c08d1;\nassign c05s = c01 + c13d1;\nassign c10s = c06 + c02d1;\nassign c15s = c11 + c07d1;\n\n// rows\n\nassign r01s = c00 + c03d3;\nassign r06s = c05 + c04d3;\nassign r11s = c10 + c09d3;\nassign r12s = c15 + c14d3;\n\nassign r02s = r01 + c00d1;\nassign r07s = r06 + c05d1;\nassign r08s = r11 + c10d1;\nassign r13s = r12 + c15d1;\n\nassign r03s = r02 + r01d1;\nassign r04s = r07 + r06d1;\nassign r09s = r08 + r11d1;\nassign r14s = r13 + r12d1;\n\nassign r00s = r03 + r02d1;\nassign r05s = r04 + r07d1;\nassign r10s = r09 + r08d1;\nassign r15s = r14 + r13d1;\n\n// Hack to bring out address one cycle earlier\nassign r00sx = c00d3 ^ { r00s[13:0], r00s[31:14] };\nassign addr = r00sx[9:0];\n\nassign out = { r15, r14d1, r13d2, r12d3, r11d3, r10, r09d1, r08d2, r07d2, r06d3, r05, r04d1, r03d1, r02d2, r01d3, r00 };\n\nalways @ (posedge clk)\nbegin\n\tc04 <= x04 ^ { c04s[24:0], c04s[31:25] };\n\tc09 <= x09 ^ { c09s[24:0], c09s[31:25] };\n\tc14 <= x14 ^ { c14s[24:0], c14s[31:25] };\n\tc03 <= x03 ^ { c03s[24:0], c03s[31:25] };\n\n\tc08 <= x08d1 ^ { c08s[22:0], c08s[31:23] };\n\tc13 <= x13d1 ^ { c13s[22:0], c13s[31:23] };\n\tc02 <= x02d1 ^ { c02s[22:0], c02s[31:23] };\n\tc07 <= x07d1 ^ { c07s[22:0], c07s[31:23] };\n\n\tc12 <= x12d2 ^ { c12s[18:0], c12s[31:19] };\n\tc01 <= x01d2 ^ { c01s[18:0], c01s[31:19] };\n\tc06 <= x06d2 ^ { c06s[18:0], c06s[31:19] };\n\tc11 <= x11d2 ^ { c11s[18:0], c11s[31:19] };\n\n\tc00 <= x00d3 ^ { c00s[13:0], c00s[31:14] };\n\tc05 <= x05d3 ^ { c05s[13:0], c05s[31:14] };\n\tc10 <= x10d3 ^ { c10s[13:0], c10s[31:14] };\n\tc15 <= x15d3 ^ { c15s[13:0], c15s[31:14] };\n\n\tr01 <= c01d1 ^ { r01s[24:0], r01s[31:25] };\n\tr06 <= c06d1 ^ { r06s[24:0], r06s[31:25] };\n\tr11 <= c11d1 ^ { r11s[24:0], r11s[31:25] };\n\tr12 <= c12d1 ^ { r12s[24:0], r12s[31:25] };\n\n\tr02 <= c02d3 ^ { r02s[22:0], r02s[31:23] };\n\tr07 <= c07d3 ^ { r07s[22:0], r07s[31:23] };\n\tr08 <= c08d3 ^ { r08s[22:0], r08s[31:23] };\n\tr13 <= c13d3 ^ { r13s[22:0], r13s[31:23] };\n\n\tr03 <= c03d5 ^ { r03s[18:0], r03s[31:19] };\n\tr04 <= c04d5 ^ { r04s[18:0], r04s[31:19] };\n\tr09 <= c09d5 ^ { r09s[18:0], r09s[31:19] };\n\tr14 <= c14d5 ^ { r14s[18:0], r14s[31:19] };\n\n\t// r00 <= c00d3 ^ { r00s[13:0], r00s[31:14] };\n\tr00 <= r00sx;\n\tr05 <= c05d3 ^ { r05s[13:0], r05s[31:14] };\n\tr10 <= c10d3 ^ { r10s[13:0], r10s[31:14] };\n\tr15 <= c15d3 ^ { r15s[13:0], r15s[31:14] };\nend\nendmodule\n"
  },
  {
    "path": "experimental/LX150-EIGHT-B/salsaengine.v",
    "content": "/* salsaengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n// NB HALFRAM no longer applies, configure via parameters ADDRBITS, THREADS\n\n// Bracket this config option in SIM so we don't accidentally leave it set in a live build\n`ifdef SIM\n//`define ONETHREAD\t// Start one thread only (for SIMULATION less confusing and faster startup)\n`endif\n\n`timescale 1ns/1ps\n\nmodule salsaengine (hash_clk, reset, din, dout, shift, start, busy, result );\n\n\tinput hash_clk;\n\tinput reset;\t// NB pbkdf_clk domain (need a long reset (at least THREADS+4) to initialize correctly, this is done in pbkdfengine (15 cycles)\n\tinput din;\n\tinput shift;\n\tinput start;\t// NB pbkdf_clk domain\n\toutput busy;\n\toutput reg result = 1'b0;\n\toutput dout;\n\t\n\t// Configure ADDRBITS to allocate RAM for core (automatically sets LOOKAHEAD_GAP)\n\t// NB do not use ADDRBITS > 13 for THREADS=8 since this corresponds to more than a full scratchpad\n\n\t// These settings are now overriden in ltcminer_icarus.v determined by LOCAL_MINERS ...\n\t// parameter ADDRBITS = 13;\t// 8MBit RAM allocated to core, full scratchpad (will not fit LX150)\n\tparameter ADDRBITS = 12;\t// 4MBit RAM allocated to core, half scratchpad\n\t// parameter ADDRBITS = 11;\t// 2MBit RAM allocated to core, quarter scratchpad\n\t// parameter ADDRBITS = 10;\t// 1MBit RAM allocated to core, eighth scratchpad\n\n\t// Do not change THREADS - this must match the salsa pipeline (code is untested for other values)\n\tparameter THREADS = 8;\t\t// NB Phase has THREADS+1 cycles\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n\tparameter THREADS_BITS = clog2(THREADS);\n\t\n\t// Workaround for range-reversal error in inactive code when ADDRBITS=13\n\tparameter ADDRBITSX = (ADDRBITS == 13) ? ADDRBITS-1 : ADDRBITS;\n\n\treg [THREADS_BITS:0]phase = 0;\n\treg [THREADS_BITS:0]phase_d = THREADS;\n\treg reset_d=0, fsmreset=0, start_d=0, fsmstart=0;\n\n\talways @ (posedge hash_clk)\t\t// Phase control and sync\n\tbegin\n\t\tphase <= (phase == THREADS) ? 0 : phase + 1;\n\t\tphase_d <= phase;\n\t\treset_d <= reset;\t\t\t// Synchronise to hash_clk domain\n\t\tfsmreset <= reset_d;\n\t\tstart_d <= start;\n\t\tfsmstart <= start_d;\n\tend\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\tparameter XSnull = 0, XSload = 1, XSmix = 2, XSram = 4;\t\t\t// One-hot since these map directly to mux contrls\n\treg [2:0] XCtl = XSnull;\n\n\tparameter R_IDLE=0, R_START=1, R_WRITE=2, R_MIX=4, R_INT=8;\t\t// Try explicit one-hot [HMMM synthesyzer changes to this gray]\n\treg [3:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg [5:0] mcount = 5'd0;\t// Salsa latency\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs\n\treg mixfeedback = 1'b0;\n\treg mixfeedback_d = 1'b0;\t// Fudge\n\treg addrsourceMix = 1'b0;\n\treg addrsourceMix_d = 1'b0;\n\treg addrsourceSave = 1'b0;\n\treg mixspecial = 1'b0;\n\treg xoren = 1'b1;\n\treg [THREADS_BITS+1:0] intcycles = 0;\t// Number of interpolation cycles required ... How many do we need? Say THREADS_BITS+1\n\n\twire [511:0] Xmix;\n\treg [511:0] X0;\n\treg [511:0] X1;\n\twire [511:0] X0in;\n\twire [511:0] X1in;\n\twire [511:0] X0out;\n\twire [511:0] X1out;\n\treg [1023:0] salsaShiftReg;\n\treg [31:0] nonce_sr;\t\t\t// In series with salsaShiftReg\n\tassign dout = salsaShiftReg[1023];\n\n\treg [511:0] Xmix_d;\n\treg [511:0] X1out_d;\n\n\t// sstate is implemented in block ram\n\treg [THREADS_BITS+38:0] sstate [THREADS-1:0];\t\t// NB initialized via a long reset (see pbkdfengine)\n\twire [3:0] mstate_in;\n\twire [10:0] cycle_in;\n\twire [5:0] mcount_in;\n\twire [9:0] writeaddr_in;\n\twire doneROM_in;\n\twire mixfeedback_in;\n\twire addrsourceMix_in;\n\twire addrsourceSave_in;\n\twire mixspecial_in;\n\twire [THREADS_BITS+1:0] intcycles_in;\t\t\t\t// How many do we need? Say THREADS_BITS+1\n\n\treg [31:0] snonce [THREADS-1:0];\t\t\t\t\t// Nonce store. Note bidirectional loading below, this will either implement\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// as registers or dual-port ram, so do NOT integrate with sstate.\n\t\n\t// NB no busy_in or result_in as these flag are NOT saved on a per-thread basis\n\n\t// Convert salsaShiftReg to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = salsaShiftReg[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\tend\n\tendgenerate\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of RAM size\n\treg [9:0] writeaddr = 10'd0;\n\n\t// TODO Delayed writeaddr adjusted for ADDRBITS (need to move the bit slicing from wr_addr assignment)\n\t// reg [ADDRBITS-THREADS_BITS:0] writeaddr_d1 = 0;\n\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr_d1 = 10'd0;\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr_d2 = 10'd0;\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr_d3 = 10'd0;\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr_d4 = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\twire [9:0] Xaddr;\n\twire [ADDRBITS-1:0]rd_addr;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0]wr_addr1;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0]wr_addr2;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0]wr_addr3;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0]wr_addr4;\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\treg ram_wren = 1'b0;\n\treg ram_wren_d = 1'b0;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\t// Top ram address is reserved for X0Save/X1save, so adjust\n\t\n\twire [15:0] memtop = 16'hfffe;\t// One less than the top memory location (per THREAD bank)\n\t\n\twire [ADDRBITS-THREADS_BITS-1:0] adj_addr;\n\n\tif (ADDRBITS < 13)\n\t\tassign adj_addr = (Xaddr[9:13-ADDRBITS] == memtop[9:13-ADDRBITS]) ?\n\t\t\t\t\t\t\tmemtop[ADDRBITS-THREADS_BITS-1:0] : Xaddr[9:13-ADDRBITS];\n\telse\n\t\tassign adj_addr = Xaddr;\n\t\n\twire [THREADS_BITS-1:0] phase_addr;\n\t(* S = \"TRUE\" *) reg [THREADS_BITS-1:0] phase_addr_d1;\n\t(* S = \"TRUE\" *) reg [THREADS_BITS-1:0] phase_addr_d2;\n\t(* S = \"TRUE\" *) reg [THREADS_BITS-1:0] phase_addr_d3;\n\t(* S = \"TRUE\" *) reg [THREADS_BITS-1:0] phase_addr_d4;\n\t\n\tassign phase_addr = phase[THREADS_BITS-1:0];\n\t// TODO remove the +1 and just derive wr_addr from phase instead of phase_d2 ?? Maybe this won't work so adj it instead)\n\tassign rd_addr = { phase_addr+1, addrsourceSave_in ? memtop[ADDRBITS-THREADS_BITS:1] : adj_addr };\t// LSB are ignored\n\t\n\tassign wr_addr1 = { phase_addr_d1, writeaddr_d1[9:13-ADDRBITS] };\n\tassign wr_addr2 = { phase_addr_d2, writeaddr_d2[9:13-ADDRBITS] };\n\tassign wr_addr3 = { phase_addr_d3, writeaddr_d3[9:13-ADDRBITS] };\n\tassign wr_addr4 = { phase_addr_d4, writeaddr_d4[9:13-ADDRBITS] };\n\n\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_1 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_2 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_3 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_4 = 0;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr1 = rd_addr | rd_addr_z_1;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr2 = rd_addr | rd_addr_z_2;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr3 = rd_addr | rd_addr_z_3;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr4 = rd_addr | rd_addr_z_4;\n\t\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (rd_addr1, wr_addr1, ram_clk, ram1_din, ram_wren_d, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (rd_addr2, wr_addr2, ram_clk, ram2_din, ram_wren_d, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (rd_addr3, wr_addr3, ram_clk, ram3_din, ram_wren_d, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (rd_addr4, wr_addr4, ram_clk, ram4_din, ram_wren_d, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = addrsourceMix_d ? { Xmix_d, X1out_d} : { X1, X0} ;\t// Registered input\n\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, mixfeedback_d, X0, X1, Xmix, X0out, X1out, Xaddr);\n\n\t// Main multiplexer\n\twire [511:0] Zbits;\n\tassign Zbits = {512{xoren}};\t\t// xoren enables xor from ram (else we load from ram)\n\t\n\t// With luck the synthesizer will interpret this correctly as one-hot control (TODO use explicit signal bits eg Xctl[0] for XSload)\n\tassign X0in = (XCtl==XSmix) ? X1out : (XCtl==XSram) ? ((mixspecial ? X1out : X0out) & Zbits) ^ ramout[511:0] : (XCtl==XSload) ? X[511:0] : X0out;\n\tassign X1in = (XCtl==XSmix) ? Xmix : (XCtl==XSram) ? ((mixspecial ? Xmix : X1out) & Zbits) ^ ramout[1023:512] : (XCtl==XSload) ? X[1023:512] : X1out;\n\t\n\t// Salsa FSM - TODO may want to move this into a separate function (for floorplanning), see hashvariant-C\n\n\t// Hold separate state for each thread (a bit of a kludge to avoid rewriting FSM from scratch)\n\t// NB must ensure shift and result do NOT overlap by carefully controlling timing of start signal\n\t// NB Phase has THREADS+1 cycles, but we do not save the state for (phase==THREADS) as it is never active\n\t\n\tassign { mstate_in, mcount_in, writeaddr_in, cycle_in, doneROM_in, mixfeedback_in, addrsourceMix_in, addrsourceSave_in, mixspecial_in,  intcycles_in} = (phase == THREADS) ? 0 : sstate[phase];\n\n\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\n\treg busy_flag = 1'b0;\n\n`ifdef ONETHREAD\n\t// TEST CONTROLLER ... just allow a single thread to run (busy is currently a common flag)\n\t// NB the thread automatically restarts after it completes, so its a slight misnomer to say it starts once.\n\treg start_once = 1'b0;\n\twire start_flag;\n\tassign start_flag = fsmstart & ~start_once;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine\n`else\n\t// NB start_flag only has effect when a thread is at R_IDLE, ie after reset, normally a thread will automatically\n\t// restart on completion. We need to spread the R_IDLE starts evenly to ensure proper ooperation. NB the pbkdf\n\t// engine requires busy and result, but this  looks alter itself in the salsa FSM, even though these are global\n\t// flags. Reset periodically (on loadnonce in pbkdfengine) to ensure it stays in sync.\n\treg [15:0] start_count = 0;\n\t// TODO automatic configuration based on THREADS (currently assumes 8)\n\t// Each lookup_gap=2 salsa takes on average 9 * (8 * 1024 + 8 * (1024*1.5)) = 184320 clocks\n\t// so start 8 threads at 184320 / 8 = 23040 clock intervals\n\t// For lookup_gap=4 use 1024*(4+3+2+1)/4 and for lookup_gap=8 use 1024*(8+..+1)/8 ie 1024*4.5\n\tparameter START_INTERVAL = ((ADDRBITS == 12) ? 184320 : (ADDRBITS == 11) ? 258048 : 405504)\t/ THREADS;\n\treg start_flag = 1'b0;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine - this will toggle on transtion through R_START\n`endif\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tX0 <= X0in;\n\t\tX1 <= X1in;\n\n\t\tif (phase_d != THREADS)\n\t\t\tsstate[phase_d] <= fsmreset ? 0 : { mstate, mcount, writeaddr, cycle, doneROM, mixfeedback, addrsourceMix,\n\t\t\t\t\t\t\t\t\t\t\t\taddrsourceSave, mixspecial, intcycles };\n\t\tmstate <= mstate_in;\t\t// Set defaults (overridden below as necessary)\n\t\tmcount <= mcount_in;\n\t\twriteaddr <= writeaddr_in;\n\t\tcycle <= cycle_in;\n\t\tintcycles <= intcycles_in;\n\t\tdoneROM <= doneROM_in;\n\t\tmixfeedback <= mixfeedback_in;\n\t\taddrsourceMix <= addrsourceMix_in;\n\t\taddrsourceSave <= addrsourceSave_in;\n\t\tmixspecial <= mixspecial_in;\n\t\t\n\t\tmixfeedback_d <= mixfeedback;\t// Fudge\n\t\taddrsourceMix_d <= addrsourceMix;\n\t\tram_wren_d <= ram_wren;\n\n\t\t// TODO move the address slicing from wr_addr to here\n\t\twriteaddr_d1 <= addrsourceMix ? memtop[10:1] : writeaddr;\n\t\twriteaddr_d2 <= addrsourceMix ? memtop[10:1] : writeaddr;\n\t\twriteaddr_d3 <= addrsourceMix ? memtop[10:1] : writeaddr;\n\t\twriteaddr_d4 <= addrsourceMix ? memtop[10:1] : writeaddr;\n\n\t\tphase_addr_d1 <= phase;\n\t\tphase_addr_d2 <= phase;\n\t\tphase_addr_d3 <= phase;\n\t\tphase_addr_d4 <= phase;\n\n\t\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\trd_addr_z_1 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_2 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_3 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_4 <= {ADDRBITS{fsmreset}};\n\t\t\n\t\tXmix_d <= Xmix;\n\t\tX1out_d <= X1out;\n\n\t\tXCtl <= XSnull;\t\t\t\t// Default states\n\t\taddrsourceSave <= 0;\n\t\tram_wren <= 0;\n\t\txoren <= 1;\n\n\t\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\t\t`ifdef ONETHREAD\n\t\tif (fsmstart)\n\t\t\tstart_once <= 1'b1;\n\t\tif (fsmreset)\n\t\t\tstart_once <= 1'b0;\n\t\t`else\n\t\tstart_count <= start_count + 1;\n\t\t// start_flag <= 1'b0;\t\t\t// Done below when we transition out of R_IDLE\n\t\tif (fsmreset || start_count == START_INTERVAL)\n\t\tbegin\n\t\t\tstart_count <= 0;\n\t\t\tif (~fsmreset && fsmstart)\n\t\t\t\tstart_flag <= 1'b1;\n\t\tend\n\t\t`endif\n\t\t\n\t\t// Could use explicit mux for this ...\n\t\tif (shift)\n\t\tbegin\n\t\t\tsalsaShiftReg <= { salsaShiftReg[1022:0], nonce_sr[31] };\n\t\t\tnonce_sr <= { nonce_sr[30:0], din };\n\t\tend\n\t\telse\n\t\tif (XCtl==XSload && phase_d != THREADS)\t\t// Set at end of previous hash - this is executed regardless of phase\n\t\tbegin\n\t\t\tsalsaShiftReg <= { Xmix, X1out };\t// Simultaneously with XSload\n\t\t\tnonce_sr <= snonce[phase_d];\t\t// NB bidirectional load\n\t\t\tsnonce[phase_d] <= nonce_sr;\n\t\tend\n\t\t\n\t\tif (fsmreset == 1'b1)\n\t\tbegin\n\t\t\tmstate <= R_IDLE;\t\t// This will propagate to all sstate slots as we hold reset for 10 cycles\n\t\t\tbusy_flag <= 1'b0;\n\t\t\tresult <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate_in)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\t// R_IDLE only applies after reset. Normally each thread will reenter at S_START and\n\t\t\t\t\t// assumes that input data is waiting (this relies on the threads being started evenly,\n\t\t\t\t\t// hence the interface FSM at the top of this file)\n\t\t\t\t\tif ((phase!=THREADS) && start_flag)\t// Ensure (phase==THREADS) slot is never active\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSload;\t\t\t// First time only (normally done at end of previous salsa cycle=1023)\n\t\t\t\t\t\t`ifndef ONETHREAD\n\t\t\t\t\t\t\tstart_flag <= 1'b0;\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t\t// Toggle the busy flag low to ack pbkdfengine (its usually already set\n\t\t\t\t\t\t\t\t\t\t\t\t// since other threads are running)\n\t\t\t\t\t\tmstate <= R_START;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_START: begin\t\t\t\t\t// Reentry point after thread completion. ASSUMES new data is ready.\n\t\t\t\t\t\twriteaddr <= 0;\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tcycle <= 0;\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\tmixspecial <= 1'b0;\n\t\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\t\tbusy_flag <= 1'b1;\n\t\t\t\t\t\tresult <= 1'b0;\n\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Initial write cycle\n\t\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\t\tend\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\tmcount <= mcount_in + 6'd1;\n\t\t\t\t\t// 8 stages since salsa takes 4 clock cycles. NB This minimises clock cycles, but adds to\n\t\t\t\t\t// the propagation delay in the salsa. The alternative of adding a cycle or two of latency to\n\t\t\t\t\t// reduce propagation delay is SLOWER due to the extra clocks needed.\n\t\t\t\t\t// Write to ROM every 2nd cycle (NB we are writing previous data here)\n\t\t\t\t\t// NB One extra cycle is performed after ROM is complete to update X0,X1 to inital state for R_MIX\n\t\t\t\t\tif (mcount_in==0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\t\tif (writeaddr_in==1023)\n\t\t\t\t\t\t\tdoneROM <= 1'b1;\t\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\t\twriteaddr <= writeaddr_in + 10'd1;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount_in==4 || mcount_in==8)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount_in==3 || mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount_in==6 && doneROM_in)\t\t\t// Preset the address source one cycle early\n\t\t\t\t\t\taddrsourceMix <= 1'b1;\t\t\t// Remains set for duration of R_MIX\n\t\t\t\t\tif (mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tif (doneROM_in)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t\tmixspecial <= 1'b1;\t\t\t// Remains true throught R_MIX\n\t\t\t\t\t\t\t// Need this to cover the case of the initial read being interpolated\n\t\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_MIX\n\t\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr[12-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\t\tif ( Xaddr[9:13-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr[12-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\t\tif ( (Xaddr[9:13-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr[12-ADDRBITSX:0] )\n\t\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t\t// Setup to save at mcount_in==0 (also does so entering R_IDLE\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t\t// after cycle==1023 but of no consequence)\n\t\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\t\t\tram_wren <= ~|writeaddr_in[12-ADDRBITSX:0];\t// Only write non-interpolated addresses\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// Entered with mixfeedback == 0 (set at mcount_in==7 above)\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\t// The longest chain is from mixfeedback to ram address input (since XMix is not registered),\n\t\t\t\t\t// again as noted above, extra register stages would simply reduce throughput.\n\t\t\t\t\tmcount <= mcount_in + 6'd1;\n\t\t\t\t\tif (mcount_in==0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\t\tif (intcycles_in != 0)\t\t// Set in previous cycle\n\t\t\t\t\t\t\tmstate <= R_INT;\t\t// Interpolate\n\t\t\t\t\tend\n\n\t\t\t\t\tif (mcount_in==4 || mcount_in==8)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount_in==3 || mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tend\n\n\t\t\t\t\tif (mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcycle <= cycle_in + 11'd1;\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tif (cycle_in==1023)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tbusy_flag <= 1'b0;\t// Will hold at 0 for 9 clocks until set at R_START\n\t\t\t\t\t\t\tif (fsmstart)\t\t\t// Check data input is ready\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tXCtl <= XSload;\t\t// Initial load else we overwrite input NB This is\n\t\t\t\t\t\t\t\t\t\t\t\t\t// executed on the next cycle, regardless of phase\n\t\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\t\tmstate <= R_START;\t// Restart immediately\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tmstate <= R_IDLE;\t// Wait for start_flag\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_WRITE\n\t\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr[12-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\t\tif ( Xaddr[9:13-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr[12-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\t\tif ( (Xaddr[9:13-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr[12-ADDRBITSX:0] )\n\t\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t\t// Setup to save at mcount_in==0 (also does so entering R_IDLE\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t\t// after cycle==1023 but of no consequence)\n\t\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\t\t\n\t\t\t\tend\n\n\t\t\t\tR_INT: begin\n\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\t// Mcount has already been incremented in R_MIX\n\t\t\t\t\tmcount <= mcount_in + 6'd1;\n\t\t\t\t\tif (mcount_in==4 || mcount_in==8)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount_in==3 || mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tend\n\n\t\t\t\t\tif (mcount_in==6)\n\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data at mcount_in==8\n\n\t\t\t\t\tif (mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (intcycles_in==1)\n\t\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Setup to XOR from saved X0/X1 in ram at next cycle\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount_in==8)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tintcycles <= intcycles_in - 1;\n\t\t\t\t\t\tmcount <= 1;\t\t// Skip 0 since done above\n\t\t\t\t\t\tif (intcycles_in==1)\n\t\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\t// Else mstate remains at R_INT so we continue interpolating from mcount=1\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (mstate==R_MIX && mcount==0)\n\t\t$display (\"phase %d cycle %d Xmix %08x\\n\", phase, cycle-1, Xmix[511:480]);\n`endif\n\tend\t// always @(posedge hash_clk)\nendmodule"
  },
  {
    "path": "experimental/LX150-EIGHT-B/sgen.c",
    "content": "#include \"stdio.h\"\nint main()\n{\n\tint i; char c;\n\n\tfor (i=0; i<16; i++)\n\t\t\tprintf(\"reg [31:0] x%02dd1, x%02dd2, x%02dd3, x%02dd4, x%02dd5, x%02dd6, x%02dd7, x%02dd8, x%02dd9;\\n\",i,i,i,i,i,i,i,i,i);\n\t\t\t\n\tfor (i=0; i<16; i++)\n\t\t\tprintf(\"reg [31:0] c%02d, c%02dd1, c%02dd2, c%02dd3, c%02dd4, c%02dd5, c%02dd6, c%02dd7, c%02dd8, c%02dd9;\\n\",i,i,i,i,i,i,i,i,i,i);\n\n\tfor (i=0; i<16; i++)\n\t\t\tprintf(\"reg [31:0] r%02d, r%02dd1, r%02dd2, r%02dd3, r%02dd4, r%02dd5, r%02dd6, r%02dd7, r%02dd8, r%02dd9;\\n\",i,i,i,i,i,i,i,i,i,i);\n\n\tprintf(\"always @ (posedge clk)\\nbegin\\n\");\n\n\tc = 'x';\n\tfor (i=0; i<16; i++)\n\t{\n\t\tprintf (\"%c%02dd1 <= %c%02d;\\n\",  c, i, c, i);\n\t\tprintf (\"%c%02dd2 <= %c%02dd1;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd3 <= %c%02dd2;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd4 <= %c%02dd3;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd5 <= %c%02dd4;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd6 <= %c%02dd5;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd7 <= %c%02dd6;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd8 <= %c%02dd7;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd9 <= %c%02dd8;\\n\", c, i, c, i);\n\t}\n\t\n\tc = 'c';\n\tfor (i=0; i<16; i++)\n\t{\n\t\tprintf (\"%c%02dd1 <= %c%02d;\\n\",  c, i, c, i);\n\t\tprintf (\"%c%02dd2 <= %c%02dd1;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd3 <= %c%02dd2;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd4 <= %c%02dd3;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd5 <= %c%02dd4;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd6 <= %c%02dd5;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd7 <= %c%02dd6;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd8 <= %c%02dd7;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd9 <= %c%02dd8;\\n\", c, i, c, i);\n\t}\n\t\n\tc = 'r';\n\tfor (i=0; i<16; i++)\n\t{\n\t\tprintf (\"%c%02dd1 <= %c%02d;\\n\",  c, i, c, i);\n\t\tprintf (\"%c%02dd2 <= %c%02dd1;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd3 <= %c%02dd2;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd4 <= %c%02dd3;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd5 <= %c%02dd4;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd6 <= %c%02dd5;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd7 <= %c%02dd6;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd8 <= %c%02dd7;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd9 <= %c%02dd8;\\n\", c, i, c, i);\n\t}\n\t\n\tprintf(\"end\\n\");\n\treturn 0;\n}\n"
  },
  {
    "path": "experimental/LX150-EIGHT-B/sgen.inc",
    "content": "reg [31:0] x00d1, x00d2, x00d3, x00d4, x00d5, x00d6, x00d7, x00d8, x00d9;\nreg [31:0] x01d1, x01d2, x01d3, x01d4, x01d5, x01d6, x01d7, x01d8, x01d9;\nreg [31:0] x02d1, x02d2, x02d3, x02d4, x02d5, x02d6, x02d7, x02d8, x02d9;\nreg [31:0] x03d1, x03d2, x03d3, x03d4, x03d5, x03d6, x03d7, x03d8, x03d9;\nreg [31:0] x04d1, x04d2, x04d3, x04d4, x04d5, x04d6, x04d7, x04d8, x04d9;\nreg [31:0] x05d1, x05d2, x05d3, x05d4, x05d5, x05d6, x05d7, x05d8, x05d9;\nreg [31:0] x06d1, x06d2, x06d3, x06d4, x06d5, x06d6, x06d7, x06d8, x06d9;\nreg [31:0] x07d1, x07d2, x07d3, x07d4, x07d5, x07d6, x07d7, x07d8, x07d9;\nreg [31:0] x08d1, x08d2, x08d3, x08d4, x08d5, x08d6, x08d7, x08d8, x08d9;\nreg [31:0] x09d1, x09d2, x09d3, x09d4, x09d5, x09d6, x09d7, x09d8, x09d9;\nreg [31:0] x10d1, x10d2, x10d3, x10d4, x10d5, x10d6, x10d7, x10d8, x10d9;\nreg [31:0] x11d1, x11d2, x11d3, x11d4, x11d5, x11d6, x11d7, x11d8, x11d9;\nreg [31:0] x12d1, x12d2, x12d3, x12d4, x12d5, x12d6, x12d7, x12d8, x12d9;\nreg [31:0] x13d1, x13d2, x13d3, x13d4, x13d5, x13d6, x13d7, x13d8, x13d9;\nreg [31:0] x14d1, x14d2, x14d3, x14d4, x14d5, x14d6, x14d7, x14d8, x14d9;\nreg [31:0] x15d1, x15d2, x15d3, x15d4, x15d5, x15d6, x15d7, x15d8, x15d9;\nreg [31:0] c00, c00d1, c00d2, c00d3, c00d4, c00d5, c00d6, c00d7, c00d8, c00d9;\nreg [31:0] c01, c01d1, c01d2, c01d3, c01d4, c01d5, c01d6, c01d7, c01d8, c01d9;\nreg [31:0] c02, c02d1, c02d2, c02d3, c02d4, c02d5, c02d6, c02d7, c02d8, c02d9;\nreg [31:0] c03, c03d1, c03d2, c03d3, c03d4, c03d5, c03d6, c03d7, c03d8, c03d9;\nreg [31:0] c04, c04d1, c04d2, c04d3, c04d4, c04d5, c04d6, c04d7, c04d8, c04d9;\nreg [31:0] c05, c05d1, c05d2, c05d3, c05d4, c05d5, c05d6, c05d7, c05d8, c05d9;\nreg [31:0] c06, c06d1, c06d2, c06d3, c06d4, c06d5, c06d6, c06d7, c06d8, c06d9;\nreg [31:0] c07, c07d1, c07d2, c07d3, c07d4, c07d5, c07d6, c07d7, c07d8, c07d9;\nreg [31:0] c08, c08d1, c08d2, c08d3, c08d4, c08d5, c08d6, c08d7, c08d8, c08d9;\nreg [31:0] c09, c09d1, c09d2, c09d3, c09d4, c09d5, c09d6, c09d7, c09d8, c09d9;\nreg [31:0] c10, c10d1, c10d2, c10d3, c10d4, c10d5, c10d6, c10d7, c10d8, c10d9;\nreg [31:0] c11, c11d1, c11d2, c11d3, c11d4, c11d5, c11d6, c11d7, c11d8, c11d9;\nreg [31:0] c12, c12d1, c12d2, c12d3, c12d4, c12d5, c12d6, c12d7, c12d8, c12d9;\nreg [31:0] c13, c13d1, c13d2, c13d3, c13d4, c13d5, c13d6, c13d7, c13d8, c13d9;\nreg [31:0] c14, c14d1, c14d2, c14d3, c14d4, c14d5, c14d6, c14d7, c14d8, c14d9;\nreg [31:0] c15, c15d1, c15d2, c15d3, c15d4, c15d5, c15d6, c15d7, c15d8, c15d9;\nreg [31:0] r00, r00d1, r00d2, r00d3, r00d4, r00d5, r00d6, r00d7, r00d8, r00d9;\nreg [31:0] r01, r01d1, r01d2, r01d3, r01d4, r01d5, r01d6, r01d7, r01d8, r01d9;\nreg [31:0] r02, r02d1, r02d2, r02d3, r02d4, r02d5, r02d6, r02d7, r02d8, r02d9;\nreg [31:0] r03, r03d1, r03d2, r03d3, r03d4, r03d5, r03d6, r03d7, r03d8, r03d9;\nreg [31:0] r04, r04d1, r04d2, r04d3, r04d4, r04d5, r04d6, r04d7, r04d8, r04d9;\nreg [31:0] r05, r05d1, r05d2, r05d3, r05d4, r05d5, r05d6, r05d7, r05d8, r05d9;\nreg [31:0] r06, r06d1, r06d2, r06d3, r06d4, r06d5, r06d6, r06d7, r06d8, r06d9;\nreg [31:0] r07, r07d1, r07d2, r07d3, r07d4, r07d5, r07d6, r07d7, r07d8, r07d9;\nreg [31:0] r08, r08d1, r08d2, r08d3, r08d4, r08d5, r08d6, r08d7, r08d8, r08d9;\nreg [31:0] r09, r09d1, r09d2, r09d3, r09d4, r09d5, r09d6, r09d7, r09d8, r09d9;\nreg [31:0] r10, r10d1, r10d2, r10d3, r10d4, r10d5, r10d6, r10d7, r10d8, r10d9;\nreg [31:0] r11, r11d1, r11d2, r11d3, r11d4, r11d5, r11d6, r11d7, r11d8, r11d9;\nreg [31:0] r12, r12d1, r12d2, r12d3, r12d4, r12d5, r12d6, r12d7, r12d8, r12d9;\nreg [31:0] r13, r13d1, r13d2, r13d3, r13d4, r13d5, r13d6, r13d7, r13d8, r13d9;\nreg [31:0] r14, r14d1, r14d2, r14d3, r14d4, r14d5, r14d6, r14d7, r14d8, r14d9;\nreg [31:0] r15, r15d1, r15d2, r15d3, r15d4, r15d5, r15d6, r15d7, r15d8, r15d9;\nalways @ (posedge clk)\nbegin\nx00d1 <= x00;\nx00d2 <= x00d1;\nx00d3 <= x00d2;\nx00d4 <= x00d3;\nx00d5 <= x00d4;\nx00d6 <= x00d5;\nx00d7 <= x00d6;\nx00d8 <= x00d7;\nx00d9 <= x00d8;\nx01d1 <= x01;\nx01d2 <= x01d1;\nx01d3 <= x01d2;\nx01d4 <= x01d3;\nx01d5 <= x01d4;\nx01d6 <= x01d5;\nx01d7 <= x01d6;\nx01d8 <= x01d7;\nx01d9 <= x01d8;\nx02d1 <= x02;\nx02d2 <= x02d1;\nx02d3 <= x02d2;\nx02d4 <= x02d3;\nx02d5 <= x02d4;\nx02d6 <= x02d5;\nx02d7 <= x02d6;\nx02d8 <= x02d7;\nx02d9 <= x02d8;\nx03d1 <= x03;\nx03d2 <= x03d1;\nx03d3 <= x03d2;\nx03d4 <= x03d3;\nx03d5 <= x03d4;\nx03d6 <= x03d5;\nx03d7 <= x03d6;\nx03d8 <= x03d7;\nx03d9 <= x03d8;\nx04d1 <= x04;\nx04d2 <= x04d1;\nx04d3 <= x04d2;\nx04d4 <= x04d3;\nx04d5 <= x04d4;\nx04d6 <= x04d5;\nx04d7 <= x04d6;\nx04d8 <= x04d7;\nx04d9 <= x04d8;\nx05d1 <= x05;\nx05d2 <= x05d1;\nx05d3 <= x05d2;\nx05d4 <= x05d3;\nx05d5 <= x05d4;\nx05d6 <= x05d5;\nx05d7 <= x05d6;\nx05d8 <= x05d7;\nx05d9 <= x05d8;\nx06d1 <= x06;\nx06d2 <= x06d1;\nx06d3 <= x06d2;\nx06d4 <= x06d3;\nx06d5 <= x06d4;\nx06d6 <= x06d5;\nx06d7 <= x06d6;\nx06d8 <= x06d7;\nx06d9 <= x06d8;\nx07d1 <= x07;\nx07d2 <= x07d1;\nx07d3 <= x07d2;\nx07d4 <= x07d3;\nx07d5 <= x07d4;\nx07d6 <= x07d5;\nx07d7 <= x07d6;\nx07d8 <= x07d7;\nx07d9 <= x07d8;\nx08d1 <= x08;\nx08d2 <= x08d1;\nx08d3 <= x08d2;\nx08d4 <= x08d3;\nx08d5 <= x08d4;\nx08d6 <= x08d5;\nx08d7 <= x08d6;\nx08d8 <= x08d7;\nx08d9 <= x08d8;\nx09d1 <= x09;\nx09d2 <= x09d1;\nx09d3 <= x09d2;\nx09d4 <= x09d3;\nx09d5 <= x09d4;\nx09d6 <= x09d5;\nx09d7 <= x09d6;\nx09d8 <= x09d7;\nx09d9 <= x09d8;\nx10d1 <= x10;\nx10d2 <= x10d1;\nx10d3 <= x10d2;\nx10d4 <= x10d3;\nx10d5 <= x10d4;\nx10d6 <= x10d5;\nx10d7 <= x10d6;\nx10d8 <= x10d7;\nx10d9 <= x10d8;\nx11d1 <= x11;\nx11d2 <= x11d1;\nx11d3 <= x11d2;\nx11d4 <= x11d3;\nx11d5 <= x11d4;\nx11d6 <= x11d5;\nx11d7 <= x11d6;\nx11d8 <= x11d7;\nx11d9 <= x11d8;\nx12d1 <= x12;\nx12d2 <= x12d1;\nx12d3 <= x12d2;\nx12d4 <= x12d3;\nx12d5 <= x12d4;\nx12d6 <= x12d5;\nx12d7 <= x12d6;\nx12d8 <= x12d7;\nx12d9 <= x12d8;\nx13d1 <= x13;\nx13d2 <= x13d1;\nx13d3 <= x13d2;\nx13d4 <= x13d3;\nx13d5 <= x13d4;\nx13d6 <= x13d5;\nx13d7 <= x13d6;\nx13d8 <= x13d7;\nx13d9 <= x13d8;\nx14d1 <= x14;\nx14d2 <= x14d1;\nx14d3 <= x14d2;\nx14d4 <= x14d3;\nx14d5 <= x14d4;\nx14d6 <= x14d5;\nx14d7 <= x14d6;\nx14d8 <= x14d7;\nx14d9 <= x14d8;\nx15d1 <= x15;\nx15d2 <= x15d1;\nx15d3 <= x15d2;\nx15d4 <= x15d3;\nx15d5 <= x15d4;\nx15d6 <= x15d5;\nx15d7 <= x15d6;\nx15d8 <= x15d7;\nx15d9 <= x15d8;\nc00d1 <= c00;\nc00d2 <= c00d1;\nc00d3 <= c00d2;\nc00d4 <= c00d3;\nc00d5 <= c00d4;\nc00d6 <= c00d5;\nc00d7 <= c00d6;\nc00d8 <= c00d7;\nc00d9 <= c00d8;\nc01d1 <= c01;\nc01d2 <= c01d1;\nc01d3 <= c01d2;\nc01d4 <= c01d3;\nc01d5 <= c01d4;\nc01d6 <= c01d5;\nc01d7 <= c01d6;\nc01d8 <= c01d7;\nc01d9 <= c01d8;\nc02d1 <= c02;\nc02d2 <= c02d1;\nc02d3 <= c02d2;\nc02d4 <= c02d3;\nc02d5 <= c02d4;\nc02d6 <= c02d5;\nc02d7 <= c02d6;\nc02d8 <= c02d7;\nc02d9 <= c02d8;\nc03d1 <= c03;\nc03d2 <= c03d1;\nc03d3 <= c03d2;\nc03d4 <= c03d3;\nc03d5 <= c03d4;\nc03d6 <= c03d5;\nc03d7 <= c03d6;\nc03d8 <= c03d7;\nc03d9 <= c03d8;\nc04d1 <= c04;\nc04d2 <= c04d1;\nc04d3 <= c04d2;\nc04d4 <= c04d3;\nc04d5 <= c04d4;\nc04d6 <= c04d5;\nc04d7 <= c04d6;\nc04d8 <= c04d7;\nc04d9 <= c04d8;\nc05d1 <= c05;\nc05d2 <= c05d1;\nc05d3 <= c05d2;\nc05d4 <= c05d3;\nc05d5 <= c05d4;\nc05d6 <= c05d5;\nc05d7 <= c05d6;\nc05d8 <= c05d7;\nc05d9 <= c05d8;\nc06d1 <= c06;\nc06d2 <= c06d1;\nc06d3 <= c06d2;\nc06d4 <= c06d3;\nc06d5 <= c06d4;\nc06d6 <= c06d5;\nc06d7 <= c06d6;\nc06d8 <= c06d7;\nc06d9 <= c06d8;\nc07d1 <= c07;\nc07d2 <= c07d1;\nc07d3 <= c07d2;\nc07d4 <= c07d3;\nc07d5 <= c07d4;\nc07d6 <= c07d5;\nc07d7 <= c07d6;\nc07d8 <= c07d7;\nc07d9 <= c07d8;\nc08d1 <= c08;\nc08d2 <= c08d1;\nc08d3 <= c08d2;\nc08d4 <= c08d3;\nc08d5 <= c08d4;\nc08d6 <= c08d5;\nc08d7 <= c08d6;\nc08d8 <= c08d7;\nc08d9 <= c08d8;\nc09d1 <= c09;\nc09d2 <= c09d1;\nc09d3 <= c09d2;\nc09d4 <= c09d3;\nc09d5 <= c09d4;\nc09d6 <= c09d5;\nc09d7 <= c09d6;\nc09d8 <= c09d7;\nc09d9 <= c09d8;\nc10d1 <= c10;\nc10d2 <= c10d1;\nc10d3 <= c10d2;\nc10d4 <= c10d3;\nc10d5 <= c10d4;\nc10d6 <= c10d5;\nc10d7 <= c10d6;\nc10d8 <= c10d7;\nc10d9 <= c10d8;\nc11d1 <= c11;\nc11d2 <= c11d1;\nc11d3 <= c11d2;\nc11d4 <= c11d3;\nc11d5 <= c11d4;\nc11d6 <= c11d5;\nc11d7 <= c11d6;\nc11d8 <= c11d7;\nc11d9 <= c11d8;\nc12d1 <= c12;\nc12d2 <= c12d1;\nc12d3 <= c12d2;\nc12d4 <= c12d3;\nc12d5 <= c12d4;\nc12d6 <= c12d5;\nc12d7 <= c12d6;\nc12d8 <= c12d7;\nc12d9 <= c12d8;\nc13d1 <= c13;\nc13d2 <= c13d1;\nc13d3 <= c13d2;\nc13d4 <= c13d3;\nc13d5 <= c13d4;\nc13d6 <= c13d5;\nc13d7 <= c13d6;\nc13d8 <= c13d7;\nc13d9 <= c13d8;\nc14d1 <= c14;\nc14d2 <= c14d1;\nc14d3 <= c14d2;\nc14d4 <= c14d3;\nc14d5 <= c14d4;\nc14d6 <= c14d5;\nc14d7 <= c14d6;\nc14d8 <= c14d7;\nc14d9 <= c14d8;\nc15d1 <= c15;\nc15d2 <= c15d1;\nc15d3 <= c15d2;\nc15d4 <= c15d3;\nc15d5 <= c15d4;\nc15d6 <= c15d5;\nc15d7 <= c15d6;\nc15d8 <= c15d7;\nc15d9 <= c15d8;\nr00d1 <= r00;\nr00d2 <= r00d1;\nr00d3 <= r00d2;\nr00d4 <= r00d3;\nr00d5 <= r00d4;\nr00d6 <= r00d5;\nr00d7 <= r00d6;\nr00d8 <= r00d7;\nr00d9 <= r00d8;\nr01d1 <= r01;\nr01d2 <= r01d1;\nr01d3 <= r01d2;\nr01d4 <= r01d3;\nr01d5 <= r01d4;\nr01d6 <= r01d5;\nr01d7 <= r01d6;\nr01d8 <= r01d7;\nr01d9 <= r01d8;\nr02d1 <= r02;\nr02d2 <= r02d1;\nr02d3 <= r02d2;\nr02d4 <= r02d3;\nr02d5 <= r02d4;\nr02d6 <= r02d5;\nr02d7 <= r02d6;\nr02d8 <= r02d7;\nr02d9 <= r02d8;\nr03d1 <= r03;\nr03d2 <= r03d1;\nr03d3 <= r03d2;\nr03d4 <= r03d3;\nr03d5 <= r03d4;\nr03d6 <= r03d5;\nr03d7 <= r03d6;\nr03d8 <= r03d7;\nr03d9 <= r03d8;\nr04d1 <= r04;\nr04d2 <= r04d1;\nr04d3 <= r04d2;\nr04d4 <= r04d3;\nr04d5 <= r04d4;\nr04d6 <= r04d5;\nr04d7 <= r04d6;\nr04d8 <= r04d7;\nr04d9 <= r04d8;\nr05d1 <= r05;\nr05d2 <= r05d1;\nr05d3 <= r05d2;\nr05d4 <= r05d3;\nr05d5 <= r05d4;\nr05d6 <= r05d5;\nr05d7 <= r05d6;\nr05d8 <= r05d7;\nr05d9 <= r05d8;\nr06d1 <= r06;\nr06d2 <= r06d1;\nr06d3 <= r06d2;\nr06d4 <= r06d3;\nr06d5 <= r06d4;\nr06d6 <= r06d5;\nr06d7 <= r06d6;\nr06d8 <= r06d7;\nr06d9 <= r06d8;\nr07d1 <= r07;\nr07d2 <= r07d1;\nr07d3 <= r07d2;\nr07d4 <= r07d3;\nr07d5 <= r07d4;\nr07d6 <= r07d5;\nr07d7 <= r07d6;\nr07d8 <= r07d7;\nr07d9 <= r07d8;\nr08d1 <= r08;\nr08d2 <= r08d1;\nr08d3 <= r08d2;\nr08d4 <= r08d3;\nr08d5 <= r08d4;\nr08d6 <= r08d5;\nr08d7 <= r08d6;\nr08d8 <= r08d7;\nr08d9 <= r08d8;\nr09d1 <= r09;\nr09d2 <= r09d1;\nr09d3 <= r09d2;\nr09d4 <= r09d3;\nr09d5 <= r09d4;\nr09d6 <= r09d5;\nr09d7 <= r09d6;\nr09d8 <= r09d7;\nr09d9 <= r09d8;\nr10d1 <= r10;\nr10d2 <= r10d1;\nr10d3 <= r10d2;\nr10d4 <= r10d3;\nr10d5 <= r10d4;\nr10d6 <= r10d5;\nr10d7 <= r10d6;\nr10d8 <= r10d7;\nr10d9 <= r10d8;\nr11d1 <= r11;\nr11d2 <= r11d1;\nr11d3 <= r11d2;\nr11d4 <= r11d3;\nr11d5 <= r11d4;\nr11d6 <= r11d5;\nr11d7 <= r11d6;\nr11d8 <= r11d7;\nr11d9 <= r11d8;\nr12d1 <= r12;\nr12d2 <= r12d1;\nr12d3 <= r12d2;\nr12d4 <= r12d3;\nr12d5 <= r12d4;\nr12d6 <= r12d5;\nr12d7 <= r12d6;\nr12d8 <= r12d7;\nr12d9 <= r12d8;\nr13d1 <= r13;\nr13d2 <= r13d1;\nr13d3 <= r13d2;\nr13d4 <= r13d3;\nr13d5 <= r13d4;\nr13d6 <= r13d5;\nr13d7 <= r13d6;\nr13d8 <= r13d7;\nr13d9 <= r13d8;\nr14d1 <= r14;\nr14d2 <= r14d1;\nr14d3 <= r14d2;\nr14d4 <= r14d3;\nr14d5 <= r14d4;\nr14d6 <= r14d5;\nr14d7 <= r14d6;\nr14d8 <= r14d7;\nr14d9 <= r14d8;\nr15d1 <= r15;\nr15d2 <= r15d1;\nr15d3 <= r15d2;\nr15d4 <= r15d3;\nr15d5 <= r15d4;\nr15d6 <= r15d5;\nr15d7 <= r15d6;\nr15d8 <= r15d7;\nr15d9 <= r15d8;\nend\n"
  },
  {
    "path": "experimental/LX150-EIGHT-B/test_icarus.v",
    "content": "// Testbench for ltcminer_icarus.v\n\n`timescale 1ns/1ps\n\n`ifdef SIM\t\t\t\t\t// Avoids wrong top selected if included in ISE/PlanAhead sources\nmodule test_ltcminer ();\n\n\treg clk = 1'b0;\n\treg [31:0] cycle = 32'd0;\n\n\tinitial begin\n\t\tclk = 0;\n\t\t\n\t\twhile(1)\n\t\tbegin\n\t\t\t#5 clk = 1; #5 clk = 0;\n\t\tend\n\tend\n\n\talways @ (posedge clk)\n\tbegin\n\t\tcycle <= cycle + 32'd1;\n\tend\n\t\n\t// Running with default zero's for the data1..3 regs.\n\t// tx_hash=553a4b69b43913a61b42013ce210f713eaa7332e48cda1bdf3b93b10161d0876 at 187,990 nS and\n\t// final_hash (if SIM is defined) at 188,000 nS with golden_nonce_match flag NOT set since it is\n\t// not a diff=32 share. To test golden_nonce, just tweak the target eg 31'hffffffff will match everything\n\t\n\t// With serial input(at comm_clk_frequency=1_000_000), we get rx_done at t=70,220nS, however there is already a\n\t// PBKDF2_SHA256_80_128 loaded in Xbuf (for nonce=00000001). The first final_hash at 188,000 nS is corrupted as\n\t// the input data has changed from all 0's. The Xbuf starts salsa rom at t=188,000 but the nonce is incorrectly\n\t// taken from the newly loaded data so once salsa in complete it also generates a corrupt final_hash at ~362,000 nS.\n\t// Nonce is incremented then the newly loaded data starts PBKDF2_SHA256_80_128, so we must supply a nonce 1 less\n\t// than the expected golden_nonce. The correct PBKDF2_SHA256_80_128 is ready at ~ 197,000 nS. We get final_hash for\n\t// the corrupted work at ~362,000 nS then our required golden_nonce is at 536,180 nS.\n\t// This is only really a problem for simulation. With live hashing we just lose 2 nonces every time getwork is\n\t// loaded, which isn't a big deal.\n\t\t\n\twire RxD;\n\twire TxD;\n\twire extminer_rxd = 0;\n\twire extminer_txd;\n\twire [3:0] dip = 0;\n\twire [3:0] led;\n\twire TMP_SCL=1, TMP_SDA=1, TMP_ALERT=1;\n\t\n\tparameter comm_clk_frequency = 1_000_000;\t// Speeds up serial loading enormously rx_done is at t=70,220nS\n\tparameter baud_rate = 115_200;\n\t\n\tltcminer_icarus #(.comm_clk_frequency(comm_clk_frequency)) uut\n\t\t(clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\t// Send serial data - 84 bytes, matches on nonce 318f (included in data)\n\t// NB starting nonce is 381e NOT 381f (see note above)\n\t\n\t// NORMAL...\n\t// reg [671:0] data = 672'h000007ff0000318e7e71441b141fe951b2b0c7dfc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af75575618e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\n\t// DYNPLL...\n\treg [671:0] data = 672'h55aa07ff0000318e7e71441b141fe951b2b0c7dfc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af75575618e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\t\n\treg\t\t\tserial_send = 0;\n\twire\t\tserial_busy;\n\treg [31:0]\tdata_32 = 0;\n\treg [31:0]\tstart_cycle = 0;\n\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(baud_rate)) sertx (.clk(clk), .TxD(RxD), .send(serial_send), .busy(serial_busy), .word(data_32));\n\n\t// TUNE this according to comm_clk_frequency so we send a single getwork (else it gets overwritten with 0's)\n\tparameter stop_cycle = 7020;\t\t// For comm_clk_frequency=1_000_000\n\t// parameter stop_cycle = 0;\t\t\t// Use this to DISABLE sending data\n\talways @ (posedge clk)\n\tbegin\n\t\tserial_send <= 0;\t\t\t\t// Default\n\t\t// Send data every time tx goes idle (NB the !serial_send is to prevent serial_send\n\t\t// going high for two cycles since serial_busy arrives one cycle after serial_send)\n\t\tif (cycle > 5 && cycle < stop_cycle && !serial_busy && !serial_send)\n\t\tbegin\n\t\t\tserial_send <= 1;\n\t\t\tdata_32 <= data[671:640];\n\t\t\tdata <= { data[639:0], 32'd0 };\n\t\t\tstart_cycle <= cycle;\t\t// Remember each start cycle (makes debugging easier)\n\t\tend\n\tend\n\nendmodule\n`endif"
  },
  {
    "path": "experimental/LX150-EIGHT-B/xilinx_dpram.v",
    "content": "// xilinx_ram.v - inferring the ram seems to work fine\n\nmodule ram # ( parameter ADDRBITS=10 ) (\n\traddr,\n\twaddr,\n\tclock,\n\tdata,\n\twren,\n\tq);\n\n\tinput\t[ADDRBITS-1:0]  raddr;\n\tinput\t[ADDRBITS-1:0]  waddr;\n\tinput\t  clock;\n\tinput\t[255:0]  data;\n\tinput\t  wren;\n\toutput\t[255:0]  q;\n\n\t//synthesis attribute ram_style of store is block\n\treg [255:0] store [(2 << (ADDRBITS-1))-1:0];\n\treg[ADDRBITS-1:0] raddr_reg;\n\t\n\talways @ (posedge clock)\n\tbegin\n\t\traddr_reg <= raddr;\n\t\tif (wren)\n\t\t\tstore[waddr] <= data;\n\tend\n\t\n\tassign q = store[raddr_reg];\n\t\t\t\nendmodule"
  },
  {
    "path": "experimental/LX150-EIGHT-B/xilinx_dyn_pll.v",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 1995-2011 Xilinx, Inc.  All rights reserved.\n////////////////////////////////////////////////////////////////////////////////\n//   ____  ____ \n//  /   /\\/   / \n// /___/  \\  /    Vendor: Xilinx \n// \\   \\   \\/     Version : 13.1\n//  \\   \\         Application : xaw2verilog\n//  /   /         Filename : main_pll.v\n// /___/   /\\     Timestamp : 06/03/2011 01:58:13\n// \\   \\  /  \\ \n//  \\___\\/\\___\\ \n//\n//Command: xaw2verilog -st /home/teknohog/dcm2/ipcore_dir/./main_pll.xaw /home/teknohog/dcm2/ipcore_dir/./main_pll\n//Design Name: main_pll\n//Device: xc3s500e-4fg320\n//\n// Module main_pll\n// Generated by Xilinx Architecture Wizard\n// Written for synthesis tool: XST\n\n`timescale 1ns / 1ps\n\nmodule dyn_pll # (parameter SPEED_MHZ = 25 )\n\t(CLKIN_IN, \n\tCLKFX1_OUT, \n\tCLKFX2_OUT, \n\tCLKDV_OUT,\n\tDCM_SP_LOCKED_OUT,\n\tdcm_progclk,\n\tdcm_progdata,\n\tdcm_progen,\n\tdcm_reset,\n\tdcm_progdone,\n\tdcm_locked,\n\tdcm_status);\n\t\n\tinput CLKIN_IN;\n\twire CLKIN_IBUFG_OUT;\n\twire CLK0_OUT;\n\toutput CLKFX1_OUT;\n\toutput CLKFX2_OUT;\n\toutput CLKDV_OUT;\n\toutput DCM_SP_LOCKED_OUT;\n\n\tinput dcm_progclk;\n\tinput dcm_progdata;\n\tinput dcm_progen;\n\tinput dcm_reset;\n\toutput dcm_progdone;\n\toutput dcm_locked;\n\toutput [2:1] dcm_status;\n\t\n\twire CLKFB_IN;\n\twire CLKIN_IBUFG;\n\twire CLK0_BUF;\n\twire CLKFX1_BUF;\n\twire CLKFX2_BUF;\n\twire CLKDV_BUF;\n\twire GND_BIT;\n\twire dcm_progclk_buf;\n\n\tassign GND_BIT = 0;\n\tassign CLKIN_IBUFG_OUT = CLKIN_IBUFG;\n\tassign CLK0_OUT = CLKFB_IN;\n\t\n\tIBUFG  CLKIN_IBUFG_INST (.I(CLKIN_IN), \n\t\t.O(CLKIN_IBUFG));\n\tBUFG  CLK0_BUFG_INST (.I(CLK0_BUF), \n\t\t.O(CLKFB_IN));\n\tBUFG  CLKFX1_BUFG_INST (.I(CLKFX1_BUF), \n\t\t.O(CLKFX1_OUT));\n\tBUFG  CLKFX2_BUFG_INST (.I(CLKFX2_BUF), \n\t\t.O(CLKFX2_OUT));\n\tBUFG  CLKDV_BUFG_INST (.I(CLKDV_BUF), \n\t\t.O(CLKDV_OUT));\n\tBUFG  DCMPROGCLK_BUFG_INST (.I(dcm_progclk), \n\t\t.O(dcm_progclk_buf));\n\n\t// 100 MHZ osc gives fixed 50MHz CLKFX1, 12.5MHZ CLKDV\n\tDCM_SP #( .CLK_FEEDBACK(\"1X\"), .CLKDV_DIVIDE(8.0), .CLKFX_DIVIDE(8),\n\t\t.CLKFX_MULTIPLY(4), .CLKIN_DIVIDE_BY_2(\"FALSE\"), \n\t\t.CLKIN_PERIOD(10.000), .CLKOUT_PHASE_SHIFT(\"NONE\"), \n\t\t.DESKEW_ADJUST(\"SYSTEM_SYNCHRONOUS\"), .DFS_FREQUENCY_MODE(\"LOW\"), \n\t\t.DLL_FREQUENCY_MODE(\"LOW\"), .DUTY_CYCLE_CORRECTION(\"TRUE\"), \n\t\t.FACTORY_JF(16'hC080), .PHASE_SHIFT(0), .STARTUP_WAIT(\"FALSE\") ) \n\t\tDCM_SP_INST (.CLKFB(CLKFB_IN), \n\t\t.CLKIN(CLKIN_IBUFG), \n\t\t.DSSEN(GND_BIT), \n\t\t.PSCLK(GND_BIT), \n\t\t.PSEN(GND_BIT), \n\t\t.PSINCDEC(GND_BIT), \n\t\t.RST(GND_BIT), \n\t\t.CLKDV(CLKDV_BUF), \n\t\t.CLKFX(CLKFX1_BUF), \n\t\t.CLKFX180(), \n\t\t.CLK0(CLK0_BUF), \n\t\t.CLK2X(), \n\t\t.CLK2X180(), \n\t\t.CLK90(), \n\t\t.CLK180(), \n\t\t.CLK270(), \n\t\t.LOCKED(DCM_SP_LOCKED_OUT), \n\t\t.PSDONE(), \n\t\t.STATUS());\n\n\tDCM_CLKGEN #(\n\t\t.CLKFX_DIVIDE(100),\t\t\t// 100Mhz osc so gives steps of 1MHz\n\t\t.CLKFX_MULTIPLY(SPEED_MHZ),\n\t\t.CLKFXDV_DIVIDE(2),\t\t\t// Unused\n\t\t.CLKIN_PERIOD(10.0),\n\t\t.CLKFX_MD_MAX(0.000),\n\t\t.SPREAD_SPECTRUM(\"NONE\"),\n\t\t.STARTUP_WAIT(\"FALSE\")\n\t\t) \n\t\tDCM_CLKGEN_INST (\n\t\t.CLKIN(CLKIN_IBUFG),\n\t\t.CLKFX(CLKFX2_BUF),\n\t\t.FREEZEDCM(1'b0),\n\t\t.PROGCLK(dcm_progclk_buf),\n\t\t.PROGDATA(dcm_progdata),\n\t\t.PROGEN(dcm_progen),\n\t\t.PROGDONE(dcm_progdone),\n\t\t.LOCKED(dcm_locked),\n\t\t.STATUS(dcm_status),\n\t\t.RST(dcm_reset)\n\t\t);\n\nendmodule\n"
  },
  {
    "path": "experimental/LX150-EIGHT-C/README.txt",
    "content": "LX150-EIGHT-C\n\nEight threads running through a fully pipelined salsa (though we still roll it\nfour times and repeat for the block mix). Automatically sets the LOOKAHEAD_GAP\nto 2,4, or 8 depending on the number of cores selected.\n\nThis version has a 10 stage pipeline (compared to 9 in LX150-EIGHT-B) to\nreduce RAM address propagation delay.\n"
  },
  {
    "path": "experimental/LX150-EIGHT-C/dyn_pll_ctrl.v",
    "content": "module dyn_pll_ctrl # (parameter SPEED_MHZ = 25, parameter SPEED_LIMIT = 100, parameter SPEED_MIN = 25, parameter OSC_MHZ = 100)\n\t(clk,\n\tclk_valid,\n\tspeed_in,\n\tstart,\n\tprogclk,\n\tprogdata,\n\tprogen,\n\treset,\n\tlocked,\n\tstatus);\n\n\tinput clk;\t\t\t\t// NB Assumed to be 12.5MHz uart_clk\n\tinput clk_valid;\t\t// Drive from LOCKED output of first dcm (ie uart_clk valid)\n\tinput [7:0] speed_in;\n\tinput start;\n\toutput reg progclk = 0;\n\toutput reg progdata = 0;\n\toutput reg progen = 0;\n\toutput reg reset = 0;\n\tinput locked;\n\tinput [2:1] status;\n\n\t// NB spec says to use (dval-1) and (mval-1), but I don't think we need to be that accurate\n\t//    and this saves an adder. Feel free to amend it.\n\treg [23:0] watchdog = 0;\n\treg [7:0] state = 0;\n\treg [7:0] dval = OSC_MHZ;\t// Osc clock speed (hence mval scales in MHz)\n\treg [7:0] mval = SPEED_MHZ;\n\treg start_d1 = 0;\n\t\n\talways @ (posedge clk)\n\tbegin\n\t\tprogclk <= ~progclk;\n\t\tstart_d1 <= start;\n\t\treset <= 1'b0;\n\t\t\n\t\t// Watchdog is just using locked, perhaps also need | ~status[2]\n\t\tif (locked)\n\t\t\twatchdog <= 0;\n\t\telse\n\t\t\twatchdog <= watchdog + 1'b1;\n\t\t\n\t\tif (watchdog[23])\t\t// Approx 670mS at 12.5MHz - NB spec is 5ms to lock at >50MHz CLKIN (50ms at <50MHz CLKIN)\n\t\tbegin\t\t\t\t\t// but allow longer just in case\n\t\t\twatchdog <= 0;\n\t\t\treset <= 1'b1;\t\t// One cycle at 12.5MHz should suffice (requirment is 3 CLKIN at 100MHz)\n\t\tend\n\t\t\n\t\tif (~clk_valid)\t\t\t// Try not to run while clk is unstable\n\t\tbegin\n\t\t\tprogen <= 0;\n\t\t\tprogdata <= 0;\n\t\t\tstate <= 0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\n\t\t\t// The documentation is unclear as to whether the DCM loads data on positive or negative edge. The timing\n\t\t\t// diagram unhelpfully shows data changing on the positive edge, which could mean either its sampled on\n\t\t\t// negative, or it was clocked on positive! However the following (WRONGLY) says NEGATIVE ...\n\t\t\t// http://forums.xilinx.com/t5/Spartan-Family-FPGAs/Spartan6-DCM-CLKGEN-does-PROGCLK-have-a-maximum-period-minimum/td-p/175642\n\t\t\t// BUT this can lock up the DCM, positive clock seems more reliable (but it can still lock up for low values of M, eg 2).\n\t\t\t// Added SPEED_MIN to prevent this (and positive clock is correct, after looking at other implementations eg ztex/theseven)\n\t\t\n\t\t\tif ((start || start_d1) && state==0 && speed_in >= SPEED_MIN && speed_in <= SPEED_LIMIT && progclk==1)\t// positive clock\n\t\t\t// if ((start || start_d1) && state==0 && speed_in >= SPEED_MIN && speed_in <= SPEED_LIMIT && progclk==0)\t// negative clock\n\t\t\tbegin\n\t\t\t\tprogen <= 0;\n\t\t\t\tprogdata <= 0;\n\t\t\t\tmval <= speed_in;\n\t\t\t\tdval <= OSC_MHZ;\n\t\t\t\tstate <= 1;\n\t\t\tend\n\t\t\tif (state != 0)\n\t\t\t\tstate <= state + 1'd1;\n\t\t\tcase (state)\t\t// Even values to sync with progclk\n\t\t\t\t// Send D\n\t\t\t\t2: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\t\tprogdata <= 1;\n\t\t\t\tend\n\t\t\t\t4: begin\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t6,8,10,12,14,16,18,20: begin\n\t\t\t\t\tprogdata <= dval[0];\n\t\t\t\t\tdval[6:0] <= dval[7:1];\n\t\t\t\tend\n\t\t\t\t22: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t// Send M\n\t\t\t\t32: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\t\tprogdata <= 1;\n\t\t\t\tend\n\t\t\t\t36,38,40,42,44,46,48,50: begin\n\t\t\t\t\tprogdata <= mval[0];\n\t\t\t\t\tmval[6:0] <= mval[7:1];\n\t\t\t\tend\n\t\t\t\t52: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t// Send GO - NB 1 clock cycle\n\t\t\t\t62: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\tend\n\t\t\t\t64: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\tend\n\t\t\t\t// We should wait on progdone/locked, but just go straight back to idle\n\t\t\t\t254: begin\n\t\t\t\t\tstate <= 0;\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n\tend\nendmodule\n"
  },
  {
    "path": "experimental/LX150-EIGHT-C/ltcminer_icarus.ucf",
    "content": "# Based on https://github.com/ngzhang/Icarus/blob/master/FPGA_project/Src/fpgaminer_top.ucf\n\nNET \"hash_clk\" TNM_NET = \"hash_clk\";\nNET \"pbkdf_clk\" TNM_NET = \"pbkdf_clk\";\nNET \"uart_clk\" TNM_NET = \"uart_clk\";\n\n# 90MHz hash_clk (it may route better specifying a slightly slower clock)\nTIMESPEC TS_hash_clk = PERIOD \"hash_clk\" 90 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\n# 50MHz pbkdf_clk\nTIMESPEC TS_pbkdf_clk = PERIOD \"pbkdf_clk\" 50 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\n# 12.5MHz uart_clk\nTIMESPEC TS_uart_clk = PERIOD \"uart_clk\" 12.5 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\nNET \"osc_clk\" LOC = J1 | IOSTANDARD = LVCMOS33;\n\n# serial port receive & transmit\nNET \"RxD\" LOC = D1 | IOSTANDARD = LVCMOS33;\nNET \"TxD\" LOC = B1 | IOSTANDARD = LVCMOS33;\n\n# TTL level serial port: ja3 = rxd, ja2 = txd\nNET \"extminer_txd[0]\" LOC = D22 | IOSTANDARD = LVCMOS33;\nNET \"extminer_rxd[0]\" LOC = B22 | IOSTANDARD = LVCMOS33;\n\nNET \"led[0]\" LOC = A18 | IOSTANDARD = LVCMOS33;\nNET \"led[1]\" LOC = B18 | IOSTANDARD = LVCMOS33;\nNET \"led[2]\" LOC = A17 | IOSTANDARD = LVCMOS33;\nNET \"led[3]\" LOC = A16 | IOSTANDARD = LVCMOS33;\n\nNET \"dip[0]\" LOC = A4 | IOSTANDARD = LVCMOS33;\nNET \"dip[1]\" LOC = D6 | IOSTANDARD = LVCMOS33;\nNET \"dip[2]\" LOC = C6 | IOSTANDARD = LVCMOS33;\nNET \"dip[3]\" LOC = C8 | IOSTANDARD = LVCMOS33;\n\nNET \"TMP_SCL\" LOC = C1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_SDA\" LOC = E1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_ALERT\" LOC = C3 | IOSTANDARD = LVCMOS33 | PULLUP;\n"
  },
  {
    "path": "experimental/LX150-EIGHT-C/ltcminer_icarus.v",
    "content": "/* ltcminer_icarus.v copyright kramble 2013\n * Based on https://github.com/teknohog/Open-Source-FPGA-Bitcoin-Miner/tree/master/projects/Xilinx_cluster_cgminer\n * Hub code for a cluster of miners using async links\n * by teknohog\n */\n\n`include \"../../source/sha-256-functions.v\"\n`include \"../../source/sha256_transform.v\"\n// `include \"../../ICARUS-LX150/xilinx_pll.v\"\t// Only needed if not USE_DYN_PLL\n`include \"../../ICARUS-LX150/uart_receiver.v\"\n`include \"../../ICARUS-LX150/uart_transmitter.v\"\n`include \"../../ICARUS-LX150/serial.v\"\n`include \"../../ICARUS-LX150/serial_hub.v\"\n`include \"../../ICARUS-LX150/hub_core.v\"\n`include \"../../ICARUS-LX150/pwm_fade.v\"\n\nmodule ltcminer_icarus (osc_clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n// NB SPEED_MHZ resolution is 5MHz steps to keep pll divide ratio sensible. Change the divider in xilinx_pll.v if you\n// want other steps (1MHz is not sensible as it requires divide 100 which is not in the allowed range 1..32 for DCM_SP)\n// New dyn_pll has 1MHz resolution and can be changed by sending a specific getwork packet (uses top bytes of target)\n\n`define USE_DYN_PLL\t\t// Enable new dyn_pll\n\n`ifdef SPEED_MHZ\n\tparameter SPEED_MHZ = `SPEED_MHZ;\n`else\n\tparameter SPEED_MHZ = 50;\t\t\t\t\t\t// Default to slow, use dynamic config to ramp up in realtime\n`endif\n\n`ifdef SPEED_LIMIT\n\tparameter SPEED_LIMIT = `SPEED_LIMIT;\t\t\t// Fastest speed accepted by dyn_pll config\n`else\n\tparameter SPEED_LIMIT = 150;\t\t\t\t\t// Deliberately conservative, increase at own risk\n`endif\n\n`ifdef SERIAL_CLK\n\tparameter comm_clk_frequency = `SERIAL_CLK;\n`else\n\tparameter comm_clk_frequency = 12_500_000;\t\t// 100MHz divide 8\n`endif\n\n`ifdef BAUD_RATE\n\tparameter BAUD_RATE = `BAUD_RATE;\n`else\n\tparameter BAUD_RATE = 115_200;\n`endif\n\n// kramble - nonce distribution is crude using top 4 bits of nonce so max LOCAL_MINERS = 8\n// teknohog's was more sophisticated, but requires modification of hashcore.v\n\n// Miners on the same FPGA with this hub\n`ifdef LOCAL_MINERS\n\tparameter LOCAL_MINERS = `LOCAL_MINERS;\n`else\n\tparameter LOCAL_MINERS = 4;\t\t\t\t\t\t// One to four cores (configures ADDRBITS automatically)\n`endif\n\n`ifdef ADDRBITS\n\tparameter ADDRBITS = `ADDRBITS;\t\t\t\t\t// Override for simulation or a quick ISE build (eg one 10 bit core)\n`else\n\tparameter ADDRBITS = 12 - clog2(LOCAL_MINERS);\t// Automatically selects largest RAM that will fit LX150\n`endif\n\n// kramble - nonce distribution only works for a single external port \n`ifdef EXT_PORTS\n\tparameter EXT_PORTS = `EXT_PORTS;\n`else\n\tparameter EXT_PORTS = 1;\n`endif\n\n\tlocalparam SLAVES = LOCAL_MINERS + EXT_PORTS;\n\n\tinput osc_clk;\n\twire hash_clk, uart_clk, pbkdf_clk;\n\n`ifdef USE_DYN_PLL\n\twire first_dcm_locked, dcm_progclk, dcm_progdata, dcm_progen, dcm_reset, dcm_progdone, dcm_locked;\n\twire [2:1] dcm_status;\n`endif\n\n`ifndef SIM\n\t`ifdef USE_DYN_PLL\n\t\tdyn_pll # (.SPEED_MHZ(SPEED_MHZ)) dyn_pll_blk\n\t\t\t(osc_clk, \n\t\t\tpbkdf_clk, \n\t\t\thash_clk, \n\t\t\tuart_clk,\n\t\t\tfirst_dcm_locked,\n\t\t\tdcm_progclk,\n\t\t\tdcm_progdata,\n\t\t\tdcm_progen,\n\t\t\tdcm_reset,\n\t\t\tdcm_progdone,\n\t\t\tdcm_locked,\n\t\t\tdcm_status);\n\t`else\n\t\tmain_pll # (.SPEED_MHZ(SPEED_MHZ)) pll_blk (.CLKIN_IN(osc_clk), .CLKFX_OUT(hash_clk), .CLKDV_OUT(uart_clk));\n\t\tassign pbkdf_clk = uart_clk;\n\t`endif\n`else\n\tassign hash_clk = osc_clk;\n\tassign uart_clk = osc_clk;\n\tassign pbkdf_clk = osc_clk;\n\t`ifdef USE_DYN_PLL\n\t\tassign first_dcm_locked = 1'b1;\n\t\tassign dcm_progdone = 1'b1;\n\t\tassign dcm_locked = 1'b1;\n\t\tassign dcm_status = 0;\n\t`endif\t\n`endif\n\n`ifdef USE_DYN_PLL\n\treg [7:0] dyn_pll_speed = SPEED_MHZ;\n\treg dyn_pll_start = 0;\n\tparameter OSC_MHZ = 100;\t\t// Clock oscillator (used for divider ratio)\n\tdyn_pll_ctrl # (.SPEED_MHZ(SPEED_MHZ), .SPEED_LIMIT(SPEED_LIMIT), .OSC_MHZ(OSC_MHZ)) dyn_pll_ctrl_blk\n\t\t(uart_clk,\t\t\t// NB uses uart_clk as its just osc/8 and should always be valid\n\t\tfirst_dcm_locked,\t// ... but we check it anyway\n\t\tdyn_pll_speed,\n\t\tdyn_pll_start,\n\t\tdcm_progclk,\n\t\tdcm_progdata,\n\t\tdcm_progen,\n\t\tdcm_reset,\n\t\tdcm_locked,\n\t\tdcm_status);\n`endif\n      \n\tinput TMP_SCL, TMP_SDA, TMP_ALERT;\t// Unused but set to PULLUP so as to avoid turning on the HOT LED\n\t\t\t\t\t\t\t\t\t\t// TODO implement I2C protocol to talk to temperature sensor chip (TMP101?)\n\t\t\t\t\t\t\t\t\t\t// and drive FAN speed control output.\n\n\tinput [3:0]dip;\n\twire reset, nonce_chip;\n\tassign reset = dip[0];\t\t\t// Not used\n\tassign nonce_chip = dip[1];\t\t// Distinguishes between the two Icarus FPGA's\n\n\t// Work distribution is simply copying to all miners, so no logic\n\t// needed there, simply copy the RxD.\n\tinput\tRxD;\n\toutput\tTxD;\n\n\t// Results from the input buffers (in serial_hub.v) of each slave\n\twire [SLAVES*32-1:0]\tslave_nonces;\n\twire [SLAVES*32-1:0]\tslave_debug_sr;\n\twire [SLAVES-1:0]\t\tnew_nonces;\n\n\t// Using the same transmission code as individual miners from serial.v\n\twire\t\tserial_send;\n\twire\t\tserial_busy;\n\twire [31:0]\tgolden_nonce;\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) sertx (.clk(uart_clk), .TxD(TxD), .send(serial_send), .busy(serial_busy), .word(golden_nonce));\n\n\thub_core #(.SLAVES(SLAVES)) hc (.uart_clk(uart_clk), .new_nonces(new_nonces), .golden_nonce(golden_nonce), .serial_send(serial_send), .serial_busy(serial_busy), .slave_nonces(slave_nonces));\n\n\t// Common workdata input for local miners\n\twire [255:0]\tdata1, data2;\n\twire [127:0]\tdata3;\n\twire [31:0]\t\ttarget;\n\treg  [31:0]\t\ttargetreg = 32'h000007ff;\t// Start at sane value (overwritten by serial_receive)\n\twire\t\t\trx_done;\t\t// Signals hashcore to reset the nonce\n\t\t\t\t\t\t\t\t\t// NB in my implementation, it loads the nonce from data3 which should be fine as\n\t\t\t\t\t\t\t\t\t// this should be zero, but also supports testing using non-zero nonces.\n\n\t// Synchronise across clock domains from uart_clk to hash_clk\n\t// This probably looks amateurish (mea maxima culpa, novice verilogger at work), but should be OK\n\treg rx_done_toggle = 1'b0;\t\t// uart_clk domain\n\talways @ (posedge uart_clk)\n\t\trx_done_toggle <= rx_done_toggle ^ rx_done;\n\n\treg rx_done_toggle_d1 = 1'b0;\t// hash_clk domain\n\treg rx_done_toggle_d2 = 1'b0;\n\treg rx_done_toggle_d3 = 1'b0;\n\t\n\twire loadnonce;\n\tassign loadnonce = rx_done_toggle_d3 ^ rx_done_toggle_d2;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\trx_done_toggle_d1 <= rx_done_toggle;\n\t\trx_done_toggle_d2 <= rx_done_toggle_d1;\n\t\trx_done_toggle_d3 <= rx_done_toggle_d2;\n\t\tif (loadnonce)\n\t\t\ttargetreg <= target;\n\tend\n\t// End of clock domain sync\n\n\twire [31:0] mod_target;\n\n`ifdef USE_DYN_PLL\n\t// Top byte of target is clock multiplier, 2nd byte is validation (one's complement of clock multiplier)\n\t// These bytes are always zero in normal getwork, so we now hard code in mod_target and use them to set clock speed.\n\t// NB The pll controller is in uart_clk domain so use serial_receive signals directly\n\t// wire [7:0]invtarg;\t\t\t\t\t// Just checking the syntax in simulator, DELETE\n\t// assign invtarg = ~target[24:16];\n\talways @ (posedge uart_clk)\n\tbegin\n\t\tdyn_pll_start <= 0;\n\t\t// A sanity check to reduce the risk of speed being set to garbage\n\t\t// Top byte of target is speed, second byte MUST be its inverse, and neither must be zero (which also rules out all ones)\n\t\tif (rx_done && target[31:24] != dyn_pll_speed && target[31:24] != 0 && target[23:16] != 0 && target[31:24] == ~target[23:16])\n\t\t// if (rx_done && target[31:24] != dyn_pll_speed && target[31:24] != 0)\t// Simpler version for DEBUG, does no verification\n\t\tbegin\n\t\t\tdyn_pll_speed <= target[31:24];\n\t\t\tdyn_pll_start <= 1;\n\t\tend\n\tend\n\tassign mod_target = { 16'd0, targetreg[15:0] };\t// Ignore top two bytes\n`else\n\t// Its better to always hard-wire the 16 MSB to zero ... if comms noise sets these bits it completely de-syncs,\n\t// generating a continuous stream of golden_nonces overwhelming the python driver which can't then reset the target.\n\t// assign mod_target = targetreg;\t\t\t\t// Original 32 bit target\n\tassign mod_target = { 16'd0, targetreg[15:0] };\t// Ignore top two bytes\n`endif\n\t\n\tserial_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) serrx (.clk(uart_clk), .RxD(RxD), .data1(data1),\n\t\t\t\t\t\t.data2(data2), .data3(data3), .target(target), .rx_done(rx_done));\n\n\t// Local miners now directly connected\n\tgenerate\n\t\tgenvar i;\n\t\tfor (i = 0; i < LOCAL_MINERS; i = i + 1)\n\t\t// begin: for_local_miners ... too verbose, so...\n\t\tbegin: miners\n\t\t\twire [31:0] nonce_out;\t// Not used\n\t\t\twire [2:0] nonce_core = i;\n\t\t\twire gn_match;\n\t\t\twire salsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift;\n\t\t\twire [3:0] dummy;\t// So we can ignore top 4 bits of slave_debug_sr\n\n\t\t\t// Currently one pbkdfengine per salsaengine - TODO share the pbkdfengine for several salsaengines\n\t\t\tpbkdfengine P (.hash_clk(hash_clk), .pbkdf_clk(pbkdf_clk), .data1(data1), .data2(data2), .data3(data3), .target(mod_target),\n\t\t\t\t.nonce_msb({nonce_chip, nonce_core}), .nonce_out(nonce_out), .golden_nonce_out(slave_nonces[i*32+31:i*32]),\n\t\t\t\t.golden_nonce_match(gn_match), .loadnonce(loadnonce),\n\t\t\t\t.salsa_din(salsa_din), .salsa_dout(salsa_dout), .salsa_busy(salsa_busy), .salsa_result(salsa_result),\n\t\t\t\t.salsa_reset(salsa_reset), .salsa_start(salsa_start), .salsa_shift(salsa_shift));\n\n\t\t\tsalsaengine #(.ADDRBITS(ADDRBITS)) S (.hash_clk(hash_clk), .reset(salsa_reset), .din(salsa_din), .dout(salsa_dout),\n\t\t\t\t.shift(salsa_shift), .start(salsa_start), .busy(salsa_busy), .result(salsa_result) );\n\t\t\t\t\t\n\t\t\t// Synchronise across clock domains from pbkdf_clk to uart_clk for: assign new_nonces[i] = gn_match;\n\t\t\treg gn_match_toggle = 1'b0;\t\t// hash_clk domain\n\t\t\talways @ (posedge pbkdf_clk)\n\t\t\t\tgn_match_toggle <= gn_match_toggle ^ gn_match;\n\n\t\t\treg gn_match_toggle_d1 = 1'b0;\t// uart_clk domain\n\t\t\treg gn_match_toggle_d2 = 1'b0;\n\t\t\treg gn_match_toggle_d3 = 1'b0;\n\n\t\t\tassign new_nonces[i] = gn_match_toggle_d3 ^ gn_match_toggle_d2;\n\n\t\t\talways @ (posedge uart_clk)\n\t\t\tbegin\n\t\t\t\tgn_match_toggle_d1 <= gn_match_toggle;\n\t\t\t\tgn_match_toggle_d2 <= gn_match_toggle_d1;\n\t\t\t\tgn_match_toggle_d3 <= gn_match_toggle_d2;\n\t\t\tend\n\t\t\t// End of clock domain sync\n\t\tend // for\n\tendgenerate\n\n\t// External miner ports, results appended to the same\n\t// slave_nonces/new_nonces as local ones\n\toutput [EXT_PORTS-1:0] extminer_txd;\n\tinput [EXT_PORTS-1:0]  extminer_rxd;\n\t// wire [EXT_PORTS-1:0]  extminer_rxd_debug = 1'b1;\t// DISABLE INPUT\n\tassign extminer_txd = {EXT_PORTS{RxD}};\n\n\tgenerate\n\t\tgenvar j;\n\t\tfor (j = LOCAL_MINERS; j < SLAVES; j = j + 1)\n\t\t// begin: for_ports ... too verbose, so ...\n\t\tbegin: ports\n\t\t\tslave_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) slrx (.clk(uart_clk), .RxD(extminer_rxd[j-LOCAL_MINERS]), .nonce(slave_nonces[j*32+31:j*32]), .new_nonce(new_nonces[j]));\n\t\tend\n\tendgenerate\n\n\toutput [3:0] led;\n\tassign led[1] = ~RxD;\n\t// assign led[2] = ~TxD;\n\t// assign led[3] = ~ (TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED - held low (the TMP pins are PULLUP, this is a fudge to\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// avoid warning about unused inputs)\n\t\n\tassign led[3] = ~first_dcm_locked | ~dcm_locked | dcm_status[2] | ~(TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED now dcm status\n\n`define FLASHCLOCK\t\t// Gives some feedback as the the actual clock speed\n\n`ifdef FLASHCLOCK\n\treg [26:0] hash_count = 0;\n\treg [3:0] sync_hash_count = 0;\n\talways @ (posedge uart_clk)\n\t\tif (rx_done)\n\t\t\tsync_hash_count[0] <= ~sync_hash_count[0];\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tsync_hash_count[3:1] <= sync_hash_count[2:0];\n\t\thash_count <= hash_count + 1'b1;\n\t\tif (sync_hash_count[3] != sync_hash_count[2])\n\t\t\thash_count <= 0;\n\tend\n\tassign led[2] = hash_count[26];\n`else\n\tassign led[2] = ~TxD;\n`endif\n\n\t// Light up only from locally found nonces, not ext_port results\n\tpwm_fade pf (.clk(uart_clk), .trigger(|new_nonces[LOCAL_MINERS-1:0]), .drive(led[0]));\n   \nendmodule\n"
  },
  {
    "path": "experimental/LX150-EIGHT-C/pbkdfengine.v",
    "content": "/* pbkdfengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`define ICARUS\t\t\t// Comment this out when using the altera virtual_wire interface in ltcminer.v\n\t\n`timescale 1ns/1ps\n\nmodule pbkdfengine\n\t(hash_clk, pbkdf_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce,\n\t\t\tsalsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift);\n\n\tinput hash_clk;\t\t\t// Just drives shift register\n\tinput pbkdf_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\n\toutput [31:0] nonce_out;\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\n\tinput salsa_dout;\n\toutput salsa_din;\n\tinput salsa_busy, salsa_result;\t// NB hash_clk domain\n\toutput salsa_reset;\n\toutput salsa_start;\n\toutput reg salsa_shift = 1'b0;\t// NB hash_clk domain\n\n\treg [3:0]resetcycles = 4'd0;\n\treg reset = 1'b0;\n\tassign salsa_reset = reset;\t\t// Propagate reset to salsaengine\n\n`ifdef WANTCYCLICRESET\t\t\n\treg [23:0]cycresetcount = 24'd0;\n`endif\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\t// Hard code a 15 cycle reset (NB assumes THREADS=8 in salsaengine, else we need more)\n\t\t// NB hash_clk is faster than pbkdf_clk so the salsaengine will actually be initialised well before\n\t\t// this period ends, but keep to 15 for now as simulation uses equal pbkdf and salsa clock speeds.\n\t\tresetcycles <= resetcycles + 1'd1;\n\t\tif (resetcycles == 0)\n\t\t\treset <= 1'b1;\n\t\tif (resetcycles == 15)\n\t\tbegin\n\t\t\treset <= 1'b0;\n\t\t\tresetcycles <= 15;\n\t\tend\n`ifdef WANTCYCLICRESET\t\t\n\t\t// Cyclical reset every 2_500_000 clocks to ensure salsa pipeline does not drift out of sync\n\t\t// This may be unneccessary if we reset every loadnonce\n\t\t// Actually it seems to do more harm than good, so disabled\n\t\tcycresetcount <= cycresetcount + 1'd1;\n\t\tif (cycresetcount == 2_500_000)\t// 10 per second at 25MHz (adjust as neccessary)\n\t\tbegin\n\t\t\tcycresetcount <= 24'd0;\n\t\t\tresetcycles <= 4'd0;\n\t\tend\n`endif\t\t\n\t\t// Reset on loadnonce (the hash results will be junk anyway since data changes, so no loss of shares)\n\t\tif (loadnonce)\n\t\t\tresetcycles <= 4'd0;\n\tend\n\t\n\t`ifndef ICARUS\n\treg [31:0] nonce_previous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\t`endif\n\n\t`ifndef NOMULTICORE\n\t`ifdef SIM\n\t\treg [27:0] nonce_cnt = 28'h318f;\t// Start point for simulation (NB also define SIM in serial.v)\n\t`else\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t`endif\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\tassign nonce_out = nonce;\n\n\treg [31:0] nonce_sr = 32'd0;\t\t// Nonce is shifted to salsaengine for storage/retrieval (hash_clk domain)\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\treg [2:0] nonce_wait = 3'd0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [2:0] blockcnt = 3'd0;\t\t// Takes values 1..5 for block iteration\n\treg [1023:0] Xbuf = 1024'd0;\t// Shared input/output buffer and shift register (hash_clk domain)\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\tassign salsa_din = Xbuf[1023];\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\t\n\t// MixOut is little-endian word format to match scrypt.c so convert back to big-endian\n\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] mix;\n\t\tassign mix = Xbuf[`IDX(i)];\t\t// NB MixOut now shares Xbuf since shifted in/out\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\n\t// Interface control. This should be OK provided the threads remain evenly spaced (hence we reset on loadnonce)\n\t\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\treg Clr_SMixOutRdy = 1'b0;\n\n\treg [3:0]salsa_busy_d;\t\t\t// Sync to pbkdf_clk domain\n\treg [3:0]salsa_result_d;\n\n\twire Clr_SMixInRdy;\n\tassign Clr_SMixInRdy = SMixInRdy_state & salsa_busy_d[2] & ~salsa_busy_d[3];\t\t// Clear on transition to busy\n\t\n\twire Set_SMixOutRdy;\n\tassign Set_SMixOutRdy = ~SMixOutRdy_state & salsa_result_d[2] & ~salsa_result_d[3];\t// Set on transition to result\n\t\n\t// Clock crossing flags for shift register control (span pbkdf_clk, hash_clk domains)\n\treg [3:0]Xbuf_load_request = 1'b0;\n\treg [3:0]shift_request =  1'b0;\n\treg [3:0]shift_acknowledge = 1'b0;\n\t\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tsalsa_busy_d[0] <= salsa_busy;\t\t\t// Sync to pbkdf_clk domain\n\t\tsalsa_busy_d[3:1] <= salsa_busy_d[2:0];\n\t\tsalsa_result_d[0] <= salsa_result;\n\t\tsalsa_result_d[3:1] <= salsa_result_d[2:0];\n\t\t\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\t\t\t\n\t\t// CARE there is a race with Set_SMixInRdy, Clr_SMixOutRdy which are set in the FSM\n\t\t// Need to assert reset for several cycles to ensure consistency (acutally use 15 since salsaengine needs more)\n\t\tif (reset)\n\t\tbegin\t\t\t\t\t\t\t// Reset takes priority\n\t\t\tSMixInRdy_state <= 1'b0;\n\t\t\tSMixOutRdy_state <= 1'b0;\n\t\tend\n\tend\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\tassign salsa_start = SMixInRdy;\n\t\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz)\n\t\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_NONCE=22, S_SHIFT_IN=41, S_SHIFT_OUT=42,\t\t\t\t// Direction relative to salsa unit\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\treg start_output = 0;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\n\t\tshift_acknowledge[3:1] <= shift_acknowledge[2:0];\t// Clock crossing\n\n\t\t`ifdef ICARUS\n\t\tif (loadnonce)\t\t\t\t// Separate clock domains means comparison is unsafe\n\t\t`else\n\t\tif (loadnonce || (nonce_previous_load != data3[127:96]))\n\t\t`endif\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_previous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\t`ifndef ICARUS\n\t\t\tnonce_previous_load <= data3[127:96];\n\t\t\t`endif\n\t\tend\n\t\t\n\t\tif (reset == 1'b1)\n\t\tbegin\n\t\t\tstate <= S_IDLE;\n\t\t\tstart_output <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tif (SMixOutRdy & ~start_output)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\t// Request shifter to start\n\t\t\t\t\t\tstate <= S_SHIFT_OUT;\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (start_output ||\t// Process output\n\t\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'b0;\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\t\tblockcnt <= 3'd1;\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_sr : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\t\t\n\t\t\t\tS_B6: begin\n\t\t\t\t\t\tkhash <= tx_hash;\t\t// Save temporarily (for Xbuf)\n\n\t\t\t\t\t\tXbuf_load_request[0] <= ~Xbuf_load_request[0];\t// NB also loads nonce_sr\n\n\t\t\t\t\t\tif (blockcnt == 3'd5)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tnonce_wait <= 3'd7;\n\t\t\t\t\t\t\tstate <= S_NONCE;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_NONCE: begin\n\t\t\t\t\t\t// Need to delay a few clocks for Xbuf_load_request to complete\n\t\t\t\t\t\tnonce_wait <= nonce_wait - 1'd1;\n\t\t\t\t\t\tif (nonce_wait == 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 1'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 1'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\n\t\t\t\t\t\t\tstate <= S_SHIFT_IN;\n\t\t\t\t\t\tend\n\t\t\t\t\n\t\t\t\tend\n\t\t\t\tS_SHIFT_IN: begin\t\t\t\t\t\t\t// Shifting from PBKDF2_SHA256 to salsa\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tSet_SMixInRdy <= 1'd1;\t\t\t\t// Flag salsa to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_SHIFT_OUT: begin\t\t\t\t\t\t\t// Shifting from salsa to PBKDF2_SHA256\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'd1;\t\t\t\t// Flag self to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_sr;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n\tend\n\n\t// Shift register control - NB hash_clk domain\n\t\n\treg\t[10:0]shift_count = 11'd0;\t// hash_clk domain\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tif (reset)\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b0;\n\t\t\tshift_count <= 11'd0;\n\t\tend\n\n\t\t// Clock crossing logic\n\t\tXbuf_load_request[3:1] <= Xbuf_load_request[2:0];\n\t\tif (Xbuf_load_request[3] != Xbuf_load_request[2])\n\t\tbegin\n\t\t\t// Shift output into X buffer from MSB->LSB\n\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\tXbuf[1023:768] <= khash;\n\n\t\t\tnonce_sr <= nonce;\t// Loaded several times, but of no consequence\n\t\tend\n\t\t\n\t\tshift_request[3:1] <= shift_request[2:0];\n\t\tif (shift_request[3] != shift_request[2])\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b1;\n\t\tend\n\n\t\tif (salsa_shift)\n\t\tbegin\n\t\t\tshift_count <= shift_count + 1'b1;\n\t\t\tXbuf <= { Xbuf[1022:0], nonce_sr[31] };\n\t\t\tnonce_sr <= { nonce_sr[30:0], salsa_dout };\n\t\tend\n\t\t\n\t\tif (shift_count == 1024+32-1)\n\t\tbegin\n\t\t\tshift_acknowledge[0] = ~shift_acknowledge[0];\n\t\t\tshift_count <= 0;\n\t\t\tsalsa_shift <= 0;\n\t\tend\n\tend\n\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(pbkdf_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\nendmodule"
  },
  {
    "path": "experimental/LX150-EIGHT-C/salsa_piped.v",
    "content": "/* salsa_piped.v ... fully registered salsa core (column and row results regs)\n*\n* Copyright (c) 2013 kramble\n* Derived from scrypt.c Copyright 2009 Colin Percival, 2011 ArtForz\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\nmodule salsa (clk, feedback, B, Bx, Bo, X0out, X1out, Xaddr);\n\n// Latency 9 clock cycles (4 col steps + 4 row + 1 sync), hence 4 salsa iterations in 36 cycles\n\ninput clk;\ninput feedback;\ninput [511:0]B;\ninput [511:0]Bx;\noutput [511:0]Bo;\noutput [511:0]X0out;\t// Pipelined B\noutput [511:0]X1out;\t// Pipelined Bx\noutput [9:0]Xaddr;\t\t// Address\n\nwire [511:0]xx;\t\t\t// Initial xor\nwire [511:0]xxd9;\t\t// Delayed 9 cycles\n\nwire [511:0]xr;\t\t\t// Output of salsa core\nreg [511:0]xrd;\t\t\t// Feedback ( 9th latency step to maintain sync with ram access)\nreg [511:0]xrd2;\t\t// Feedback (10th latency step to maintain sync with ram access)\n\nwire [9:0]addr;\t\t\t// Address from salsa\nreg [9:0]xxd7_addr;\n\n// X0/X1 delays ... just to check timing, probably need to use a ram location to reduce routing congestion\n\nreg [511:0]x0d1;\nreg [511:0]x0d2;\nreg [511:0]x0d3;\nreg [511:0]x0d4;\nreg [511:0]x0d5;\nreg [511:0]x0d6;\nreg [511:0]x0d7;\nreg [511:0]x0d8;\nreg [511:0]x0d9;\n\nreg [511:0]x1d1;\nreg [511:0]x1d2;\nreg [511:0]x1d3;\nreg [511:0]x1d4;\nreg [511:0]x1d5;\nreg [511:0]x1d6;\nreg [511:0]x1d7;\nreg [511:0]x1d8;\nreg [511:0]x1d9;\n\nassign X0out = x0d9;\nassign X1out = x1d9;\n\nsalsa_core salsa1 (clk, feedback ? xrd2 : xx, xr, addr);\n\nalways @ (posedge clk)\nbegin\n\txrd <= xr;\n\txrd2 <= xrd;\n\n\tx0d1 <= B;\n\tx0d2 <= x0d1;\n\tx0d3 <= x0d2;\n\tx0d4 <= x0d3;\n\tx0d5 <= x0d4;\n\tx0d6 <= x0d5;\n\tx0d7 <= x0d6;\n\tx0d8 <= x0d7;\n\tx0d9 <= x0d8;\n\t\n\tx1d1 <= Bx;\n\tx1d2 <= x1d1;\n\tx1d3 <= x1d2;\n\tx1d4 <= x1d3;\n\tx1d5 <= x1d4;\n\tx1d6 <= x1d5;\n\tx1d7 <= x1d6;\n\tx1d8 <= x1d7;\n\tx1d9 <= x1d8;\n\t\n\txxd7_addr <= x0d6[9:0] ^ x1d6[9:0];\nend\n\t\ngenvar i;\ngenerate\n\tfor (i = 0; i < 16; i = i + 1) begin : XX\n\t\t// Initial XOR. NB this adds to the propagation delay of the first salsa, may want register it.\n\t\tassign xx[`IDX(i)] = B[`IDX(i)] ^ Bx[`IDX(i)];\n\t\tassign xxd9[`IDX(i)] = x0d9[`IDX(i)] ^ x1d9[`IDX(i)];\t\t// Could do one cycle early (in reg) to save an xor delay\n\t\t// Final sum. NB Ouptut is at 8 cycle latency.\n\t\tassign Bo[`IDX(i)] = xxd9[`IDX(i)] + xrd[`IDX(i)];\n\tend\nendgenerate\n\nassign Xaddr = xxd7_addr + addr;\n\nendmodule\n\nmodule salsa_core (clk, x, out, addr);\n\ninput clk;\ninput [511:0]x;\noutput [511:0]out;\noutput [9:0]addr;\n\n// This is clunky due to my lack of verilog skills but it works so elegance can come later\n// ... actually its now gotten quite ridiculous, see KLUDGE below\n\n// Aliases for inputs\n\nwire [31:0] x00;\nwire [31:0] x01;\nwire [31:0] x02;\nwire [31:0] x03;\nwire [31:0] x04;\nwire [31:0] x05;\nwire [31:0] x06;\nwire [31:0] x07;\nwire [31:0] x08;\nwire [31:0] x09;\nwire [31:0] x10;\nwire [31:0] x11;\nwire [31:0] x12;\nwire [31:0] x13;\nwire [31:0] x14;\nwire [31:0] x15;\n\nassign x00 = x[`IDX(0)];\nassign x01 = x[`IDX(1)];\nassign x02 = x[`IDX(2)];\nassign x03 = x[`IDX(3)];\nassign x04 = x[`IDX(4)];\nassign x05 = x[`IDX(5)];\nassign x06 = x[`IDX(6)];\nassign x07 = x[`IDX(7)];\nassign x08 = x[`IDX(8)];\nassign x09 = x[`IDX(9)];\nassign x10 = x[`IDX(10)];\nassign x11 = x[`IDX(11)];\nassign x12 = x[`IDX(12)];\nassign x13 = x[`IDX(13)];\nassign x14 = x[`IDX(14)];\nassign x15 = x[`IDX(15)];\n\n// Column & Row Results (yup, I wrote a program to generate these) ...\n// Not all of these are used, but let the synthesizer take care of that for now\n// TODO prune the unused ones, may be important with certain synth settings\n\n// BEGIN KLUDGE\n`include \"sgen.inc\"\t\t\t// .inc so it does not accidentally get compiled separately as .v\n// END KLUDGE\n\nwire [31:0]c00s;\t\t\t// Column sums\nwire [31:0]c01s;\nwire [31:0]c02s;\nwire [31:0]c03s;\nwire [31:0]c04s;\nwire [31:0]c05s;\nwire [31:0]c06s;\nwire [31:0]c07s;\nwire [31:0]c08s;\nwire [31:0]c09s;\nwire [31:0]c10s;\nwire [31:0]c11s;\nwire [31:0]c12s;\nwire [31:0]c13s;\nwire [31:0]c14s;\nwire [31:0]c15s;\n\nwire [31:0]r00s;\t\t\t// Row sums\nwire [31:0]r01s;\nwire [31:0]r02s;\nwire [31:0]r03s;\nwire [31:0]r04s;\nwire [31:0]r05s;\nwire [31:0]r06s;\nwire [31:0]r07s;\nwire [31:0]r08s;\nwire [31:0]r09s;\nwire [31:0]r10s;\nwire [31:0]r11s;\nwire [31:0]r12s;\nwire [31:0]r13s;\nwire [31:0]r14s;\nwire [31:0]r15s;\n\nwire [31:0]r00sx;\n\n/* From scrypt.c\n\n#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))\n\tfor (i = 0; i < 8; i += 2) {\n\t\t// Operate on columns\n\t\tx04 ^= R(x00+x12, 7);\tx09 ^= R(x05+x01, 7);\tx14 ^= R(x10+x06, 7);\tx03 ^= R(x15+x11, 7);\n\t\tx08 ^= R(x04+x00, 9);\tx13 ^= R(x09+x05, 9);\tx02 ^= R(x14+x10, 9);\tx07 ^= R(x03+x15, 9);\n\t\tx12 ^= R(x08+x04,13);\tx01 ^= R(x13+x09,13);\tx06 ^= R(x02+x14,13);\tx11 ^= R(x07+x03,13);\n\t\tx00 ^= R(x12+x08,18);\tx05 ^= R(x01+x13,18);\tx10 ^= R(x06+x02,18);\tx15 ^= R(x11+x07,18);\n\n\t\t// Operate on rows\n\t\tx01 ^= R(x00+x03, 7);\tx06 ^= R(x05+x04, 7);\tx11 ^= R(x10+x09, 7);\tx12 ^= R(x15+x14, 7);\n\t\tx02 ^= R(x01+x00, 9);\tx07 ^= R(x06+x05, 9);\tx08 ^= R(x11+x10, 9);\tx13 ^= R(x12+x15, 9);\n\t\tx03 ^= R(x02+x01,13);\tx04 ^= R(x07+x06,13);\tx09 ^= R(x08+x11,13);\tx14 ^= R(x13+x12,13);\n\t\tx00 ^= R(x03+x02,18);\tx05 ^= R(x04+x07,18);\tx10 ^= R(x09+x08,18);\tx15 ^= R(x14+x13,18);\n\t}\n*/\n\n// cols\n\nassign c04s = x00 + x12;\nassign c09s = x05 + x01;\nassign c14s = x10 + x06;\nassign c03s = x15 + x11;\n\nassign c08s = c04 + x00d1;\nassign c13s = c09 + x05d1;\nassign c02s = c14 + x10d1;\nassign c07s = c03 + x15d1;\n\nassign c12s = c08 + c04d1;\nassign c01s = c13 + c09d1;\nassign c06s = c02 + c14d1;\nassign c11s = c07 + c03d1;\n\nassign c00s = c12 + c08d1;\nassign c05s = c01 + c13d1;\nassign c10s = c06 + c02d1;\nassign c15s = c11 + c07d1;\n\n// rows\n\nassign r01s = c00 + c03d3;\nassign r06s = c05 + c04d3;\nassign r11s = c10 + c09d3;\nassign r12s = c15 + c14d3;\n\nassign r02s = r01 + c00d1;\nassign r07s = r06 + c05d1;\nassign r08s = r11 + c10d1;\nassign r13s = r12 + c15d1;\n\nassign r03s = r02 + r01d1;\nassign r04s = r07 + r06d1;\nassign r09s = r08 + r11d1;\nassign r14s = r13 + r12d1;\n\nassign r00s = r03 + r02d1;\nassign r05s = r04 + r07d1;\nassign r10s = r09 + r08d1;\nassign r15s = r14 + r13d1;\n\n// Hack to bring out address one cycle earlier\nassign r00sx = c00d3 ^ { r00s[13:0], r00s[31:14] };\nassign addr = r00sx[9:0];\n\nassign out = { r15, r14d1, r13d2, r12d3, r11d3, r10, r09d1, r08d2, r07d2, r06d3, r05, r04d1, r03d1, r02d2, r01d3, r00 };\n\nalways @ (posedge clk)\nbegin\n\tc04 <= x04 ^ { c04s[24:0], c04s[31:25] };\n\tc09 <= x09 ^ { c09s[24:0], c09s[31:25] };\n\tc14 <= x14 ^ { c14s[24:0], c14s[31:25] };\n\tc03 <= x03 ^ { c03s[24:0], c03s[31:25] };\n\n\tc08 <= x08d1 ^ { c08s[22:0], c08s[31:23] };\n\tc13 <= x13d1 ^ { c13s[22:0], c13s[31:23] };\n\tc02 <= x02d1 ^ { c02s[22:0], c02s[31:23] };\n\tc07 <= x07d1 ^ { c07s[22:0], c07s[31:23] };\n\n\tc12 <= x12d2 ^ { c12s[18:0], c12s[31:19] };\n\tc01 <= x01d2 ^ { c01s[18:0], c01s[31:19] };\n\tc06 <= x06d2 ^ { c06s[18:0], c06s[31:19] };\n\tc11 <= x11d2 ^ { c11s[18:0], c11s[31:19] };\n\n\tc00 <= x00d3 ^ { c00s[13:0], c00s[31:14] };\n\tc05 <= x05d3 ^ { c05s[13:0], c05s[31:14] };\n\tc10 <= x10d3 ^ { c10s[13:0], c10s[31:14] };\n\tc15 <= x15d3 ^ { c15s[13:0], c15s[31:14] };\n\n\tr01 <= c01d1 ^ { r01s[24:0], r01s[31:25] };\n\tr06 <= c06d1 ^ { r06s[24:0], r06s[31:25] };\n\tr11 <= c11d1 ^ { r11s[24:0], r11s[31:25] };\n\tr12 <= c12d1 ^ { r12s[24:0], r12s[31:25] };\n\n\tr02 <= c02d3 ^ { r02s[22:0], r02s[31:23] };\n\tr07 <= c07d3 ^ { r07s[22:0], r07s[31:23] };\n\tr08 <= c08d3 ^ { r08s[22:0], r08s[31:23] };\n\tr13 <= c13d3 ^ { r13s[22:0], r13s[31:23] };\n\n\tr03 <= c03d5 ^ { r03s[18:0], r03s[31:19] };\n\tr04 <= c04d5 ^ { r04s[18:0], r04s[31:19] };\n\tr09 <= c09d5 ^ { r09s[18:0], r09s[31:19] };\n\tr14 <= c14d5 ^ { r14s[18:0], r14s[31:19] };\n\n\t// r00 <= c00d3 ^ { r00s[13:0], r00s[31:14] };\n\tr00 <= r00sx;\n\tr05 <= c05d3 ^ { r05s[13:0], r05s[31:14] };\n\tr10 <= c10d3 ^ { r10s[13:0], r10s[31:14] };\n\tr15 <= c15d3 ^ { r15s[13:0], r15s[31:14] };\nend\nendmodule\n"
  },
  {
    "path": "experimental/LX150-EIGHT-C/salsaengine.v",
    "content": "/* salsaengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n// NB HALFRAM no longer applies, configure via parameters ADDRBITS, THREADS\n\n// Bracket this config option in SIM so we don't accidentally leave it set in a live build\n`ifdef SIM\n`define ONETHREAD\t// Start one thread only (for SIMULATION less confusing and faster startup)\n`endif\n\n`timescale 1ns/1ps\n\nmodule salsaengine (hash_clk, reset, din, dout, shift, start, busy, result );\n\n\tinput hash_clk;\n\tinput reset;\t// NB pbkdf_clk domain (need a long reset (at least THREADS+4) to initialize correctly, this is done in pbkdfengine (15 cycles)\n\tinput din;\n\tinput shift;\n\tinput start;\t// NB pbkdf_clk domain\n\toutput busy;\n\toutput reg result = 1'b0;\n\toutput dout;\n\t\n\t// Configure ADDRBITS to allocate RAM for core (automatically sets LOOKAHEAD_GAP)\n\t// NB do not use ADDRBITS > 13 for THREADS=8 since this corresponds to more than a full scratchpad\n\n\t// These settings are now overriden in ltcminer_icarus.v determined by LOCAL_MINERS ...\n\t// parameter ADDRBITS = 13;\t// 8MBit RAM allocated to core, full scratchpad (will not fit LX150)\n\tparameter ADDRBITS = 12;\t// 4MBit RAM allocated to core, half scratchpad\n\t// parameter ADDRBITS = 11;\t// 2MBit RAM allocated to core, quarter scratchpad\n\t// parameter ADDRBITS = 10;\t// 1MBit RAM allocated to core, eighth scratchpad\n\n\t// Do not change THREADS - this must match the salsa pipeline (code is untested for other values)\n\tparameter THREADS = 8;\t\t// NB Phase has THREADS+1 cycles\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n\tparameter THREADS_BITS = clog2(THREADS);\n\t\n\t// Workaround for range-reversal error in inactive code when ADDRBITS=13\n\tparameter ADDRBITSX = (ADDRBITS == 13) ? ADDRBITS-1 : ADDRBITS;\n\n\treg [THREADS_BITS:0]phase = 0;\n\treg [THREADS_BITS:0]phase_d = THREADS+1;\n\treg reset_d=0, fsmreset=0, start_d=0, fsmstart=0;\n\n\talways @ (posedge hash_clk)\t\t// Phase control and sync\n\tbegin\n\t\tphase <= (phase == THREADS+1) ? 0 : phase + 1;\n\t\tphase_d <= phase;\n\t\treset_d <= reset;\t\t\t// Synchronise to hash_clk domain\n\t\tfsmreset <= reset_d;\n\t\tstart_d <= start;\n\t\tfsmstart <= start_d;\n\tend\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\tparameter XSnull = 0, XSload = 1, XSmix = 2, XSram = 4;\t\t\t// One-hot since these map directly to mux contrls\n\treg [2:0] XCtl = XSnull;\n\n\tparameter R_IDLE=0, R_START=1, R_WRITE=2, R_MIX=4, R_INT=8;\t\t// Try explicit one-hot [HMMM synthesyzer changes to this gray]\n\treg [3:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg [5:0] mcount = 5'd0;\t// Salsa latency\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs\n\treg mixfeedback = 1'b0;\n\treg mixfeedback_d = 1'b0;\t// Fudge\n\treg mixfeedback_d2 = 1'b0;\t// Fudge\n\treg addrsourceMix = 1'b0;\n\treg addrsourceMix_d = 1'b0;\n\treg addrsourceMix_d2 = 1'b0;\n\treg addrsourceSave = 1'b0;\n\treg mixspecial = 1'b0;\n\treg xoren = 1'b1;\n\treg [THREADS_BITS+1:0] intcycles = 0;\t// Number of interpolation cycles required ... How many do we need? Say THREADS_BITS+1\n\n\twire [511:0] Xmix;\n\treg [511:0] X0;\n\treg [511:0] X1;\n\treg [511:0] X0_d;\n\treg [511:0] X1_d;\n\twire [511:0] X0in;\n\twire [511:0] X1in;\n\twire [511:0] X0out;\n\twire [511:0] X1out;\n\treg [1023:0] salsaShiftReg;\n\treg [31:0] nonce_sr;\t\t\t// In series with salsaShiftReg\n\tassign dout = salsaShiftReg[1023];\n\n\treg [511:0] Xmix_d;\n\treg [511:0] X1out_d;\n\treg [511:0] Xmix_d2;\n\treg [511:0] X1out_d2;\n\n\t// sstate is implemented in block ram\n\treg [THREADS_BITS+38:0] sstate [THREADS-1:0];\t\t// NB initialized via a long reset (see pbkdfengine)\n\twire [3:0] mstate_in;\n\twire [10:0] cycle_in;\n\twire [5:0] mcount_in;\n\twire [9:0] writeaddr_in;\n\twire doneROM_in;\n\twire mixfeedback_in;\n\twire addrsourceMix_in;\n\twire addrsourceSave_in;\n\twire mixspecial_in;\n\twire [THREADS_BITS+1:0] intcycles_in;\t\t\t\t// How many do we need? Say THREADS_BITS+1\n\n\treg [31:0] snonce [THREADS-1:0];\t\t\t\t\t// Nonce store. Note bidirectional loading below, this will either implement\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// as registers or dual-port ram, so do NOT integrate with sstate.\n\t\n\t// NB no busy_in or result_in as these flag are NOT saved on a per-thread basis\n\n\t// Convert salsaShiftReg to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = salsaShiftReg[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\tend\n\tendgenerate\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of RAM size\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr = 10'd0;\n\n\t// TODO Delayed writeaddr adjusted for ADDRBITS (need to move the bit slicing from wr_addr assignment)\n\t// reg [ADDRBITS-THREADS_BITS:0] writeaddr_d1 = 0;\n\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr_d1 = 10'd0;\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr_d2 = 10'd0;\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr_d3 = 10'd0;\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr_d4 = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\twire [9:0] Xaddr;\n\t(* S = \"TRUE\" *) reg [9:0] Xaddr_d;\t// Perhaps use Xmix directly\n\twire [ADDRBITS-1:0]rd_addr;\n\twire [ADDRBITS-1:0]wr_addr1;\n\twire [ADDRBITS-1:0]wr_addr2;\n\twire [ADDRBITS-1:0]wr_addr3;\n\twire [ADDRBITS-1:0]wr_addr4;\n\t/*\n\treg [ADDRBITS-1:0]wr_addr1_d;\n\treg [ADDRBITS-1:0]wr_addr2_d;\n\treg [ADDRBITS-1:0]wr_addr3_d;\n\treg [ADDRBITS-1:0]wr_addr4_d;\n\t*/\n\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\t(* S = \"TRUE\" *) reg ram_wren = 1'b0;\n\t(* S = \"TRUE\" *) reg ram_wren_d = 1'b0;\n\t(* S = \"TRUE\" *) reg ram_wren_d2 = 1'b0;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\t// Top ram address is reserved for X0Save/X1save, so adjust\n\t\n\twire [15:0] memtop = 16'hfffe;\t// One less than the top memory location (per THREAD bank)\n\t\n\twire [ADDRBITS-THREADS_BITS-1:0] adj_addr;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-THREADS_BITS-1:0] adj_addr_d;\n\n\tif (ADDRBITS < 13)\n\t\tassign adj_addr = (Xaddr[9:13-ADDRBITS] == memtop[9:13-ADDRBITS]) ?\n\t\t\t\t\t\t\tmemtop[ADDRBITS-THREADS_BITS-1:0] : Xaddr[9:13-ADDRBITS];\n\telse\n\t\tassign adj_addr = Xaddr;\n\t\n\twire [THREADS_BITS-1:0] phase_addr;\n\t(* S = \"TRUE\" *) reg [THREADS_BITS-1:0] phase_addr_d1;\n\t(* S = \"TRUE\" *) reg [THREADS_BITS-1:0] phase_addr_d2;\n\t(* S = \"TRUE\" *) reg [THREADS_BITS-1:0] phase_addr_d3;\n\t(* S = \"TRUE\" *) reg [THREADS_BITS-1:0] phase_addr_d4;\n\t\n\tassign phase_addr = phase[THREADS_BITS-1:0];\n\t// TODO remove the +1 and just derive wr_addr from phase instead of phase_d2 ?? Maybe this won't work so adj it instead)\n\tassign rd_addr = { phase_addr+1, addrsourceSave_in ? memtop[ADDRBITS-THREADS_BITS:1] : adj_addr_d };\t// LSB are ignored\n\t\n\tassign wr_addr1 = { phase_addr_d1, writeaddr_d1[9:13-ADDRBITS] };\n\tassign wr_addr2 = { phase_addr_d2, writeaddr_d2[9:13-ADDRBITS] };\n\tassign wr_addr3 = { phase_addr_d3, writeaddr_d3[9:13-ADDRBITS] };\n\tassign wr_addr4 = { phase_addr_d4, writeaddr_d4[9:13-ADDRBITS] };\n\n\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_1 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_2 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_3 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_4 = 0;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr1 = rd_addr | rd_addr_z_1;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr2 = rd_addr | rd_addr_z_2;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr3 = rd_addr | rd_addr_z_3;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr4 = rd_addr | rd_addr_z_4;\n\t\n\t// NB wr_addr is now further registered inside ram\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (rd_addr1, wr_addr1, ram_clk, ram1_din, ram_wren_d2, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (rd_addr2, wr_addr2, ram_clk, ram2_din, ram_wren_d2, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (rd_addr3, wr_addr3, ram_clk, ram3_din, ram_wren_d2, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (rd_addr4, wr_addr4, ram_clk, ram4_din, ram_wren_d2, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = addrsourceMix_d2 ? { Xmix_d2, X1out_d2} : { X1_d, X0_d} ;\t// Registered input\n\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, mixfeedback_d, X0, X1, Xmix, X0out, X1out, Xaddr);\n\n\t// Main multiplexer\n\twire [511:0] Zbits;\n\tassign Zbits = {512{xoren}};\t\t// xoren enables xor from ram (else we load from ram)\n\t\n\t// With luck the synthesizer will interpret this correctly as one-hot control (TODO use explicit signal bits eg Xctl[0] for XSload)\n\tassign X0in = (XCtl==XSmix) ? X1out : (XCtl==XSram) ? ((mixspecial ? X1out : X0out) & Zbits) ^ ramout[511:0] : (XCtl==XSload) ? X[511:0] : X0out;\n\tassign X1in = (XCtl==XSmix) ? Xmix : (XCtl==XSram) ? ((mixspecial ? Xmix : X1out) & Zbits) ^ ramout[1023:512] : (XCtl==XSload) ? X[1023:512] : X1out;\n\t\n\t// Salsa FSM - TODO may want to move this into a separate function (for floorplanning), see hashvariant-C\n\n\t// Hold separate state for each thread (a bit of a kludge to avoid rewriting FSM from scratch)\n\t// NB must ensure shift and result do NOT overlap by carefully controlling timing of start signal\n\t// NB Phase has THREADS+1 cycles, but we do not save the state for (phase==THREADS) as it is never active\n\n\tassign { mstate_in, mcount_in, writeaddr_in, cycle_in, doneROM_in, mixfeedback_in, addrsourceMix_in, addrsourceSave_in, mixspecial_in,  intcycles_in} = (phase == THREADS || phase == THREADS+1) ? 0 : sstate[phase];\n\t\n\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\n\treg busy_flag = 1'b0;\n\t\n`ifdef ONETHREAD\n\t// TEST CONTROLLER ... just allow a single thread to run (busy is currently a common flag)\n\t// NB the thread automatically restarts after it completes, so its a slight misnomer to say it starts once.\n\treg start_once = 1'b0;\n\twire start_flag;\n\tassign start_flag = fsmstart & ~start_once;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine\n`else\n\t// NB start_flag only has effect when a thread is at R_IDLE, ie after reset, normally a thread will automatically\n\t// restart on completion. We need to spread the R_IDLE starts evenly to ensure proper ooperation. NB the pbkdf\n\t// engine requires busy and result, but this  looks alter itself in the salsa FSM, even though these are global\n\t// flags. Reset periodically (on loadnonce in pbkdfengine) to ensure it stays in sync.\n\treg [15:0] start_count = 0;\n\t// TODO automatic configuration based on THREADS (currently assumes 8)\n\t// Each lookup_gap=2 salsa takes on average 9 * (8 * 1024 + 8 * (1024*1.5)) = 184320 clocks\n\t// so start 8 threads at 184320 / 8 = 23040 clock intervals\n\t// For lookup_gap=4 use 1024*(4+3+2+1)/4 and for lookup_gap=8 use 1024*(8+..+1)/8 ie 1024*4.5\n\tparameter START_INTERVAL = ((ADDRBITS == 12) ? 184320 : (ADDRBITS == 11) ? 258048 : 405504)\t/ THREADS;\n\treg start_flag = 1'b0;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine - this will toggle on transtion through R_START\n`endif\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tX0 <= X0in;\n\t\tX1 <= X1in;\n\t\tX1_d <= X1;\n\t\tX0_d <= X0;\n\t\t\n\t\tadj_addr_d <= adj_addr;\n\n\t\tif (phase_d != THREADS && phase_d != THREADS+1)\n\t\t\tsstate[phase_d] <= fsmreset ? 0 : { mstate, mcount, writeaddr, cycle, doneROM, mixfeedback, addrsourceMix,\n\t\t\t\t\t\t\t\t\t\t\t\taddrsourceSave, mixspecial, intcycles };\n\t\tmstate <= mstate_in;\t\t// Set defaults (overridden below as necessary)\n\t\tmcount <= mcount_in;\n\t\twriteaddr <= writeaddr_in;\n\t\tcycle <= cycle_in;\n\t\tintcycles <= intcycles_in;\n\t\tdoneROM <= doneROM_in;\n\t\tmixfeedback <= mixfeedback_in;\n\t\taddrsourceMix <= addrsourceMix_in;\n\t\taddrsourceSave <= addrsourceSave_in;\n\t\tmixspecial <= mixspecial_in;\n\t\t\n\t\tmixfeedback_d <= mixfeedback;\t// Fudge\n\t\tmixfeedback_d2 <= mixfeedback_d;\t// Fudge\n\t\taddrsourceMix_d <= addrsourceMix;\n\t\taddrsourceMix_d2 <= addrsourceMix_d;\n\t\tram_wren_d <= ram_wren;\n\t\tram_wren_d2 <= ram_wren_d;\n\n\t\t// TODO move the address slicing from wr_addr to here\n\t\twriteaddr_d1 <= addrsourceMix ? memtop[10:1] : writeaddr;\n\t\twriteaddr_d2 <= addrsourceMix ? memtop[10:1] : writeaddr;\n\t\twriteaddr_d3 <= addrsourceMix ? memtop[10:1] : writeaddr;\n\t\twriteaddr_d4 <= addrsourceMix ? memtop[10:1] : writeaddr;\n\n\t\t// Now INSIDE ram\n\t\t//wr_addr1_d <= wr_addr1;\n\t\t//wr_addr2_d <= wr_addr2;\n\t\t//wr_addr3_d <= wr_addr3;\n\t\t//wr_addr4_d <= wr_addr4;\n\n\t\tphase_addr_d1 <= phase;\n\t\tphase_addr_d2 <= phase;\n\t\tphase_addr_d3 <= phase;\n\t\tphase_addr_d4 <= phase;\n\n\t\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\trd_addr_z_1 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_2 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_3 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_4 <= {ADDRBITS{fsmreset}};\n\t\t\n\t\tXmix_d <= Xmix;\n\t\tXmix_d2 <= Xmix_d;\n\t\tX1out_d <= X1out;\n\t\tX1out_d2 <= X1out_d;\n\t\tXaddr_d <= Xaddr;\t\t\t// Perhaps use Xmix directly\n\n\t\tXCtl <= XSnull;\t\t\t\t// Default states\n\t\taddrsourceSave <= 0;\n\t\tram_wren <= 0;\n\t\txoren <= 1;\n\t\t\n\t\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\t\t`ifdef ONETHREAD\n\t\tif (fsmstart && phase!=THREADS && phase!=THREADS+1)\n\t\t\tstart_once <= 1'b1;\n\t\tif (fsmreset)\n\t\t\tstart_once <= 1'b0;\n\t\t`else\n\t\tstart_count <= start_count + 1;\n\t\t// start_flag <= 1'b0;\t\t\t// Done below when we transition out of R_IDLE\n\t\tif (fsmreset || start_count == START_INTERVAL)\n\t\tbegin\n\t\t\tstart_count <= 0;\n\t\t\tif (~fsmreset && fsmstart)\n\t\t\t\tstart_flag <= 1'b1;\n\t\tend\n\t\t`endif\n\t\t\n\t\t// Could use explicit mux for this ...\n\t\tif (shift)\n\t\tbegin\n\t\t\tsalsaShiftReg <= { salsaShiftReg[1022:0], nonce_sr[31] };\n\t\t\tnonce_sr <= { nonce_sr[30:0], din};\n\t\tend\n\t\telse\n\t\tif (XCtl==XSload && phase_d != THREADS && phase_d != THREADS+1)\t\t// Set at end of previous hash - this is executed regardless of phase\n\t\tbegin\n\t\t\tsalsaShiftReg <= { Xmix, X1out };\t// Simultaneously with XSload\n\t\t\tnonce_sr <= snonce[phase_d];\t\t// NB bidirectional load\n\t\t\tsnonce[phase_d] <= nonce_sr;\n\t\tend\n\t\t\n\t\tif (fsmreset == 1'b1)\n\t\tbegin\n\t\t\tmstate <= R_IDLE;\t\t// This will propagate to all sstate slots as we hold reset for 10 cycles\n\t\t\tbusy_flag <= 1'b0;\n\t\t\tresult <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate_in)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\t// R_IDLE only applies after reset. Normally each thread will reenter at S_START and\n\t\t\t\t\t// assumes that input data is waiting (this relies on the threads being started evenly,\n\t\t\t\t\t// hence the interface FSM at the top of this file)\n\t\t\t\t\tif (phase!=THREADS && phase!=THREADS+1 && start_flag)\t// Ensure (phase==THREADS) slot is never active\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSload;\t\t\t// First time only (normally done at end of previous salsa cycle=1023)\n\t\t\t\t\t\t`ifndef ONETHREAD\n\t\t\t\t\t\t\tstart_flag <= 1'b0;\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t\t// Toggle the busy flag low to ack pbkdfengine (its usually already set\n\t\t\t\t\t\t\t\t\t\t\t\t// since other threads are running)\n\t\t\t\t\t\tmstate <= R_START;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_START: begin\t\t\t\t\t// Reentry point after thread completion. ASSUMES new data is ready.\n\t\t\t\t\t\twriteaddr <= 0;\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tcycle <= 0;\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\tmixspecial <= 1'b0;\n\t\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\t\tbusy_flag <= 1'b1;\n\t\t\t\t\t\tresult <= 1'b0;\n\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Initial write cycle\n\t\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\t\tend\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\tmcount <= mcount_in + 6'd1;\n\t\t\t\t\t// 8 stages since salsa takes 4 clock cycles. NB This minimises clock cycles, but adds to\n\t\t\t\t\t// the propagation delay in the salsa. The alternative of adding a cycle or two of latency to\n\t\t\t\t\t// reduce propagation delay is SLOWER due to the extra clocks needed.\n\t\t\t\t\t// Write to ROM every 2nd cycle (NB we are writing previous data here)\n\t\t\t\t\t// NB One extra cycle is performed after ROM is complete to update X0,X1 to inital state for R_MIX\n\t\t\t\t\tif (mcount_in==0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\t\tif (writeaddr_in==1023)\n\t\t\t\t\t\t\tdoneROM <= 1'b1;\t\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\t\twriteaddr <= writeaddr_in + 10'd1;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount_in==4 || mcount_in==8)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount_in==3 || mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount_in==6 && doneROM_in)\t\t\t// Preset the address source one cycle early\n\t\t\t\t\t\taddrsourceMix <= 1'b1;\t\t\t// Remains set for duration of R_MIX\n\t\t\t\t\tif (mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tif (doneROM_in)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t\tmixspecial <= 1'b1;\t\t\t// Remains true throught R_MIX\n\t\t\t\t\t\t\t// Need this to cover the case of the initial read being interpolated\n\t\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_MIX\n\t\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr_d[12-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\t\tif ( Xaddr_d[9:13-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr_d[12-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\t\tif ( (Xaddr_d[9:13-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr_d[12-ADDRBITSX:0] )\n\t\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t\t// Setup to save at mcount_in==0 (also does so entering R_IDLE\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t\t// after cycle==1023 but of no consequence)\n\t\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\t\t\tram_wren <= ~|writeaddr_in[12-ADDRBITSX:0];\t// Only write non-interpolated addresses\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// Entered with mixfeedback == 0 (set at mcount_in==7 above)\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\t// The longest chain is from mixfeedback to ram address input (since XMix is not registered),\n\t\t\t\t\t// again as noted above, extra register stages would simply reduce throughput.\n\t\t\t\t\tmcount <= mcount_in + 6'd1;\n\t\t\t\t\tif (mcount_in==0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\t\tif (intcycles_in != 0)\t\t// Set in previous cycle\n\t\t\t\t\t\t\tmstate <= R_INT;\t\t// Interpolate\n\t\t\t\t\tend\n\n\t\t\t\t\tif (mcount_in==4 || mcount_in==8)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount_in==3 || mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tend\n\n\t\t\t\t\tif (mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcycle <= cycle_in + 11'd1;\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tif (cycle_in==1023)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tbusy_flag <= 1'b0;\t// Will hold at 0 for 9 clocks until set at R_START\n\t\t\t\t\t\t\tif (fsmstart)\t\t\t// Check data input is ready\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tXCtl <= XSload;\t\t// Initial load else we overwrite input NB This is\n\t\t\t\t\t\t\t\t\t\t\t\t\t// executed on the next cycle, regardless of phase\n\t\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\t\tmstate <= R_START;\t// Restart immediately\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tmstate <= R_IDLE;\t// Wait for start_flag\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_WRITE\n\t\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr_d[12-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\t\tif ( Xaddr_d[9:13-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr_d[12-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\t\tif ( (Xaddr_d[9:13-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr_d[12-ADDRBITSX:0] )\n\t\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t\t// Setup to save at mcount_in==0 (also does so entering R_IDLE\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t\t// after cycle==1023 but of no consequence)\n\t\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\t\t\n\t\t\t\tend\n\n\t\t\t\tR_INT: begin\n\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\t// Mcount has already been incremented in R_MIX\n\t\t\t\t\tmcount <= mcount_in + 6'd1;\n\t\t\t\t\tif (mcount_in==4 || mcount_in==8)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount_in==3 || mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tend\n\n\t\t\t\t\tif (mcount_in==6)\n\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data at mcount_in==8\n\n\t\t\t\t\tif (mcount_in==7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (intcycles_in==1)\n\t\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Setup to XOR from saved X0/X1 in ram at next cycle\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount_in==8)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tintcycles <= intcycles_in - 1;\n\t\t\t\t\t\tmcount <= 1;\t\t// Skip 0 since done above\n\t\t\t\t\t\tif (intcycles_in==1)\n\t\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\t// Else mstate remains at R_INT so we continue interpolating from mcount=1\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (mstate==R_MIX && mcount==0)\n\t\t$display (\"phase %d cycle %d Xmix %08x\\n\", phase, cycle-1, Xmix[511:480]);\n`endif\n\tend\t// always @(posedge hash_clk)\nendmodule"
  },
  {
    "path": "experimental/LX150-EIGHT-C/sgen.c",
    "content": "#include \"stdio.h\"\nint main()\n{\n\tint i; char c;\n\n\tfor (i=0; i<16; i++)\n\t\t\tprintf(\"reg [31:0] x%02dd1, x%02dd2, x%02dd3, x%02dd4, x%02dd5, x%02dd6, x%02dd7, x%02dd8, x%02dd9;\\n\",i,i,i,i,i,i,i,i,i);\n\t\t\t\n\tfor (i=0; i<16; i++)\n\t\t\tprintf(\"reg [31:0] c%02d, c%02dd1, c%02dd2, c%02dd3, c%02dd4, c%02dd5, c%02dd6, c%02dd7, c%02dd8, c%02dd9;\\n\",i,i,i,i,i,i,i,i,i,i);\n\n\tfor (i=0; i<16; i++)\n\t\t\tprintf(\"reg [31:0] r%02d, r%02dd1, r%02dd2, r%02dd3, r%02dd4, r%02dd5, r%02dd6, r%02dd7, r%02dd8, r%02dd9;\\n\",i,i,i,i,i,i,i,i,i,i);\n\n\tprintf(\"always @ (posedge clk)\\nbegin\\n\");\n\n\tc = 'x';\n\tfor (i=0; i<16; i++)\n\t{\n\t\tprintf (\"%c%02dd1 <= %c%02d;\\n\",  c, i, c, i);\n\t\tprintf (\"%c%02dd2 <= %c%02dd1;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd3 <= %c%02dd2;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd4 <= %c%02dd3;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd5 <= %c%02dd4;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd6 <= %c%02dd5;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd7 <= %c%02dd6;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd8 <= %c%02dd7;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd9 <= %c%02dd8;\\n\", c, i, c, i);\n\t}\n\t\n\tc = 'c';\n\tfor (i=0; i<16; i++)\n\t{\n\t\tprintf (\"%c%02dd1 <= %c%02d;\\n\",  c, i, c, i);\n\t\tprintf (\"%c%02dd2 <= %c%02dd1;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd3 <= %c%02dd2;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd4 <= %c%02dd3;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd5 <= %c%02dd4;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd6 <= %c%02dd5;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd7 <= %c%02dd6;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd8 <= %c%02dd7;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd9 <= %c%02dd8;\\n\", c, i, c, i);\n\t}\n\t\n\tc = 'r';\n\tfor (i=0; i<16; i++)\n\t{\n\t\tprintf (\"%c%02dd1 <= %c%02d;\\n\",  c, i, c, i);\n\t\tprintf (\"%c%02dd2 <= %c%02dd1;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd3 <= %c%02dd2;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd4 <= %c%02dd3;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd5 <= %c%02dd4;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd6 <= %c%02dd5;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd7 <= %c%02dd6;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd8 <= %c%02dd7;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd9 <= %c%02dd8;\\n\", c, i, c, i);\n\t}\n\t\n\tprintf(\"end\\n\");\n\treturn 0;\n}\n"
  },
  {
    "path": "experimental/LX150-EIGHT-C/sgen.inc",
    "content": "reg [31:0] x00d1, x00d2, x00d3, x00d4, x00d5, x00d6, x00d7, x00d8, x00d9;\nreg [31:0] x01d1, x01d2, x01d3, x01d4, x01d5, x01d6, x01d7, x01d8, x01d9;\nreg [31:0] x02d1, x02d2, x02d3, x02d4, x02d5, x02d6, x02d7, x02d8, x02d9;\nreg [31:0] x03d1, x03d2, x03d3, x03d4, x03d5, x03d6, x03d7, x03d8, x03d9;\nreg [31:0] x04d1, x04d2, x04d3, x04d4, x04d5, x04d6, x04d7, x04d8, x04d9;\nreg [31:0] x05d1, x05d2, x05d3, x05d4, x05d5, x05d6, x05d7, x05d8, x05d9;\nreg [31:0] x06d1, x06d2, x06d3, x06d4, x06d5, x06d6, x06d7, x06d8, x06d9;\nreg [31:0] x07d1, x07d2, x07d3, x07d4, x07d5, x07d6, x07d7, x07d8, x07d9;\nreg [31:0] x08d1, x08d2, x08d3, x08d4, x08d5, x08d6, x08d7, x08d8, x08d9;\nreg [31:0] x09d1, x09d2, x09d3, x09d4, x09d5, x09d6, x09d7, x09d8, x09d9;\nreg [31:0] x10d1, x10d2, x10d3, x10d4, x10d5, x10d6, x10d7, x10d8, x10d9;\nreg [31:0] x11d1, x11d2, x11d3, x11d4, x11d5, x11d6, x11d7, x11d8, x11d9;\nreg [31:0] x12d1, x12d2, x12d3, x12d4, x12d5, x12d6, x12d7, x12d8, x12d9;\nreg [31:0] x13d1, x13d2, x13d3, x13d4, x13d5, x13d6, x13d7, x13d8, x13d9;\nreg [31:0] x14d1, x14d2, x14d3, x14d4, x14d5, x14d6, x14d7, x14d8, x14d9;\nreg [31:0] x15d1, x15d2, x15d3, x15d4, x15d5, x15d6, x15d7, x15d8, x15d9;\nreg [31:0] c00, c00d1, c00d2, c00d3, c00d4, c00d5, c00d6, c00d7, c00d8, c00d9;\nreg [31:0] c01, c01d1, c01d2, c01d3, c01d4, c01d5, c01d6, c01d7, c01d8, c01d9;\nreg [31:0] c02, c02d1, c02d2, c02d3, c02d4, c02d5, c02d6, c02d7, c02d8, c02d9;\nreg [31:0] c03, c03d1, c03d2, c03d3, c03d4, c03d5, c03d6, c03d7, c03d8, c03d9;\nreg [31:0] c04, c04d1, c04d2, c04d3, c04d4, c04d5, c04d6, c04d7, c04d8, c04d9;\nreg [31:0] c05, c05d1, c05d2, c05d3, c05d4, c05d5, c05d6, c05d7, c05d8, c05d9;\nreg [31:0] c06, c06d1, c06d2, c06d3, c06d4, c06d5, c06d6, c06d7, c06d8, c06d9;\nreg [31:0] c07, c07d1, c07d2, c07d3, c07d4, c07d5, c07d6, c07d7, c07d8, c07d9;\nreg [31:0] c08, c08d1, c08d2, c08d3, c08d4, c08d5, c08d6, c08d7, c08d8, c08d9;\nreg [31:0] c09, c09d1, c09d2, c09d3, c09d4, c09d5, c09d6, c09d7, c09d8, c09d9;\nreg [31:0] c10, c10d1, c10d2, c10d3, c10d4, c10d5, c10d6, c10d7, c10d8, c10d9;\nreg [31:0] c11, c11d1, c11d2, c11d3, c11d4, c11d5, c11d6, c11d7, c11d8, c11d9;\nreg [31:0] c12, c12d1, c12d2, c12d3, c12d4, c12d5, c12d6, c12d7, c12d8, c12d9;\nreg [31:0] c13, c13d1, c13d2, c13d3, c13d4, c13d5, c13d6, c13d7, c13d8, c13d9;\nreg [31:0] c14, c14d1, c14d2, c14d3, c14d4, c14d5, c14d6, c14d7, c14d8, c14d9;\nreg [31:0] c15, c15d1, c15d2, c15d3, c15d4, c15d5, c15d6, c15d7, c15d8, c15d9;\nreg [31:0] r00, r00d1, r00d2, r00d3, r00d4, r00d5, r00d6, r00d7, r00d8, r00d9;\nreg [31:0] r01, r01d1, r01d2, r01d3, r01d4, r01d5, r01d6, r01d7, r01d8, r01d9;\nreg [31:0] r02, r02d1, r02d2, r02d3, r02d4, r02d5, r02d6, r02d7, r02d8, r02d9;\nreg [31:0] r03, r03d1, r03d2, r03d3, r03d4, r03d5, r03d6, r03d7, r03d8, r03d9;\nreg [31:0] r04, r04d1, r04d2, r04d3, r04d4, r04d5, r04d6, r04d7, r04d8, r04d9;\nreg [31:0] r05, r05d1, r05d2, r05d3, r05d4, r05d5, r05d6, r05d7, r05d8, r05d9;\nreg [31:0] r06, r06d1, r06d2, r06d3, r06d4, r06d5, r06d6, r06d7, r06d8, r06d9;\nreg [31:0] r07, r07d1, r07d2, r07d3, r07d4, r07d5, r07d6, r07d7, r07d8, r07d9;\nreg [31:0] r08, r08d1, r08d2, r08d3, r08d4, r08d5, r08d6, r08d7, r08d8, r08d9;\nreg [31:0] r09, r09d1, r09d2, r09d3, r09d4, r09d5, r09d6, r09d7, r09d8, r09d9;\nreg [31:0] r10, r10d1, r10d2, r10d3, r10d4, r10d5, r10d6, r10d7, r10d8, r10d9;\nreg [31:0] r11, r11d1, r11d2, r11d3, r11d4, r11d5, r11d6, r11d7, r11d8, r11d9;\nreg [31:0] r12, r12d1, r12d2, r12d3, r12d4, r12d5, r12d6, r12d7, r12d8, r12d9;\nreg [31:0] r13, r13d1, r13d2, r13d3, r13d4, r13d5, r13d6, r13d7, r13d8, r13d9;\nreg [31:0] r14, r14d1, r14d2, r14d3, r14d4, r14d5, r14d6, r14d7, r14d8, r14d9;\nreg [31:0] r15, r15d1, r15d2, r15d3, r15d4, r15d5, r15d6, r15d7, r15d8, r15d9;\nalways @ (posedge clk)\nbegin\nx00d1 <= x00;\nx00d2 <= x00d1;\nx00d3 <= x00d2;\nx00d4 <= x00d3;\nx00d5 <= x00d4;\nx00d6 <= x00d5;\nx00d7 <= x00d6;\nx00d8 <= x00d7;\nx00d9 <= x00d8;\nx01d1 <= x01;\nx01d2 <= x01d1;\nx01d3 <= x01d2;\nx01d4 <= x01d3;\nx01d5 <= x01d4;\nx01d6 <= x01d5;\nx01d7 <= x01d6;\nx01d8 <= x01d7;\nx01d9 <= x01d8;\nx02d1 <= x02;\nx02d2 <= x02d1;\nx02d3 <= x02d2;\nx02d4 <= x02d3;\nx02d5 <= x02d4;\nx02d6 <= x02d5;\nx02d7 <= x02d6;\nx02d8 <= x02d7;\nx02d9 <= x02d8;\nx03d1 <= x03;\nx03d2 <= x03d1;\nx03d3 <= x03d2;\nx03d4 <= x03d3;\nx03d5 <= x03d4;\nx03d6 <= x03d5;\nx03d7 <= x03d6;\nx03d8 <= x03d7;\nx03d9 <= x03d8;\nx04d1 <= x04;\nx04d2 <= x04d1;\nx04d3 <= x04d2;\nx04d4 <= x04d3;\nx04d5 <= x04d4;\nx04d6 <= x04d5;\nx04d7 <= x04d6;\nx04d8 <= x04d7;\nx04d9 <= x04d8;\nx05d1 <= x05;\nx05d2 <= x05d1;\nx05d3 <= x05d2;\nx05d4 <= x05d3;\nx05d5 <= x05d4;\nx05d6 <= x05d5;\nx05d7 <= x05d6;\nx05d8 <= x05d7;\nx05d9 <= x05d8;\nx06d1 <= x06;\nx06d2 <= x06d1;\nx06d3 <= x06d2;\nx06d4 <= x06d3;\nx06d5 <= x06d4;\nx06d6 <= x06d5;\nx06d7 <= x06d6;\nx06d8 <= x06d7;\nx06d9 <= x06d8;\nx07d1 <= x07;\nx07d2 <= x07d1;\nx07d3 <= x07d2;\nx07d4 <= x07d3;\nx07d5 <= x07d4;\nx07d6 <= x07d5;\nx07d7 <= x07d6;\nx07d8 <= x07d7;\nx07d9 <= x07d8;\nx08d1 <= x08;\nx08d2 <= x08d1;\nx08d3 <= x08d2;\nx08d4 <= x08d3;\nx08d5 <= x08d4;\nx08d6 <= x08d5;\nx08d7 <= x08d6;\nx08d8 <= x08d7;\nx08d9 <= x08d8;\nx09d1 <= x09;\nx09d2 <= x09d1;\nx09d3 <= x09d2;\nx09d4 <= x09d3;\nx09d5 <= x09d4;\nx09d6 <= x09d5;\nx09d7 <= x09d6;\nx09d8 <= x09d7;\nx09d9 <= x09d8;\nx10d1 <= x10;\nx10d2 <= x10d1;\nx10d3 <= x10d2;\nx10d4 <= x10d3;\nx10d5 <= x10d4;\nx10d6 <= x10d5;\nx10d7 <= x10d6;\nx10d8 <= x10d7;\nx10d9 <= x10d8;\nx11d1 <= x11;\nx11d2 <= x11d1;\nx11d3 <= x11d2;\nx11d4 <= x11d3;\nx11d5 <= x11d4;\nx11d6 <= x11d5;\nx11d7 <= x11d6;\nx11d8 <= x11d7;\nx11d9 <= x11d8;\nx12d1 <= x12;\nx12d2 <= x12d1;\nx12d3 <= x12d2;\nx12d4 <= x12d3;\nx12d5 <= x12d4;\nx12d6 <= x12d5;\nx12d7 <= x12d6;\nx12d8 <= x12d7;\nx12d9 <= x12d8;\nx13d1 <= x13;\nx13d2 <= x13d1;\nx13d3 <= x13d2;\nx13d4 <= x13d3;\nx13d5 <= x13d4;\nx13d6 <= x13d5;\nx13d7 <= x13d6;\nx13d8 <= x13d7;\nx13d9 <= x13d8;\nx14d1 <= x14;\nx14d2 <= x14d1;\nx14d3 <= x14d2;\nx14d4 <= x14d3;\nx14d5 <= x14d4;\nx14d6 <= x14d5;\nx14d7 <= x14d6;\nx14d8 <= x14d7;\nx14d9 <= x14d8;\nx15d1 <= x15;\nx15d2 <= x15d1;\nx15d3 <= x15d2;\nx15d4 <= x15d3;\nx15d5 <= x15d4;\nx15d6 <= x15d5;\nx15d7 <= x15d6;\nx15d8 <= x15d7;\nx15d9 <= x15d8;\nc00d1 <= c00;\nc00d2 <= c00d1;\nc00d3 <= c00d2;\nc00d4 <= c00d3;\nc00d5 <= c00d4;\nc00d6 <= c00d5;\nc00d7 <= c00d6;\nc00d8 <= c00d7;\nc00d9 <= c00d8;\nc01d1 <= c01;\nc01d2 <= c01d1;\nc01d3 <= c01d2;\nc01d4 <= c01d3;\nc01d5 <= c01d4;\nc01d6 <= c01d5;\nc01d7 <= c01d6;\nc01d8 <= c01d7;\nc01d9 <= c01d8;\nc02d1 <= c02;\nc02d2 <= c02d1;\nc02d3 <= c02d2;\nc02d4 <= c02d3;\nc02d5 <= c02d4;\nc02d6 <= c02d5;\nc02d7 <= c02d6;\nc02d8 <= c02d7;\nc02d9 <= c02d8;\nc03d1 <= c03;\nc03d2 <= c03d1;\nc03d3 <= c03d2;\nc03d4 <= c03d3;\nc03d5 <= c03d4;\nc03d6 <= c03d5;\nc03d7 <= c03d6;\nc03d8 <= c03d7;\nc03d9 <= c03d8;\nc04d1 <= c04;\nc04d2 <= c04d1;\nc04d3 <= c04d2;\nc04d4 <= c04d3;\nc04d5 <= c04d4;\nc04d6 <= c04d5;\nc04d7 <= c04d6;\nc04d8 <= c04d7;\nc04d9 <= c04d8;\nc05d1 <= c05;\nc05d2 <= c05d1;\nc05d3 <= c05d2;\nc05d4 <= c05d3;\nc05d5 <= c05d4;\nc05d6 <= c05d5;\nc05d7 <= c05d6;\nc05d8 <= c05d7;\nc05d9 <= c05d8;\nc06d1 <= c06;\nc06d2 <= c06d1;\nc06d3 <= c06d2;\nc06d4 <= c06d3;\nc06d5 <= c06d4;\nc06d6 <= c06d5;\nc06d7 <= c06d6;\nc06d8 <= c06d7;\nc06d9 <= c06d8;\nc07d1 <= c07;\nc07d2 <= c07d1;\nc07d3 <= c07d2;\nc07d4 <= c07d3;\nc07d5 <= c07d4;\nc07d6 <= c07d5;\nc07d7 <= c07d6;\nc07d8 <= c07d7;\nc07d9 <= c07d8;\nc08d1 <= c08;\nc08d2 <= c08d1;\nc08d3 <= c08d2;\nc08d4 <= c08d3;\nc08d5 <= c08d4;\nc08d6 <= c08d5;\nc08d7 <= c08d6;\nc08d8 <= c08d7;\nc08d9 <= c08d8;\nc09d1 <= c09;\nc09d2 <= c09d1;\nc09d3 <= c09d2;\nc09d4 <= c09d3;\nc09d5 <= c09d4;\nc09d6 <= c09d5;\nc09d7 <= c09d6;\nc09d8 <= c09d7;\nc09d9 <= c09d8;\nc10d1 <= c10;\nc10d2 <= c10d1;\nc10d3 <= c10d2;\nc10d4 <= c10d3;\nc10d5 <= c10d4;\nc10d6 <= c10d5;\nc10d7 <= c10d6;\nc10d8 <= c10d7;\nc10d9 <= c10d8;\nc11d1 <= c11;\nc11d2 <= c11d1;\nc11d3 <= c11d2;\nc11d4 <= c11d3;\nc11d5 <= c11d4;\nc11d6 <= c11d5;\nc11d7 <= c11d6;\nc11d8 <= c11d7;\nc11d9 <= c11d8;\nc12d1 <= c12;\nc12d2 <= c12d1;\nc12d3 <= c12d2;\nc12d4 <= c12d3;\nc12d5 <= c12d4;\nc12d6 <= c12d5;\nc12d7 <= c12d6;\nc12d8 <= c12d7;\nc12d9 <= c12d8;\nc13d1 <= c13;\nc13d2 <= c13d1;\nc13d3 <= c13d2;\nc13d4 <= c13d3;\nc13d5 <= c13d4;\nc13d6 <= c13d5;\nc13d7 <= c13d6;\nc13d8 <= c13d7;\nc13d9 <= c13d8;\nc14d1 <= c14;\nc14d2 <= c14d1;\nc14d3 <= c14d2;\nc14d4 <= c14d3;\nc14d5 <= c14d4;\nc14d6 <= c14d5;\nc14d7 <= c14d6;\nc14d8 <= c14d7;\nc14d9 <= c14d8;\nc15d1 <= c15;\nc15d2 <= c15d1;\nc15d3 <= c15d2;\nc15d4 <= c15d3;\nc15d5 <= c15d4;\nc15d6 <= c15d5;\nc15d7 <= c15d6;\nc15d8 <= c15d7;\nc15d9 <= c15d8;\nr00d1 <= r00;\nr00d2 <= r00d1;\nr00d3 <= r00d2;\nr00d4 <= r00d3;\nr00d5 <= r00d4;\nr00d6 <= r00d5;\nr00d7 <= r00d6;\nr00d8 <= r00d7;\nr00d9 <= r00d8;\nr01d1 <= r01;\nr01d2 <= r01d1;\nr01d3 <= r01d2;\nr01d4 <= r01d3;\nr01d5 <= r01d4;\nr01d6 <= r01d5;\nr01d7 <= r01d6;\nr01d8 <= r01d7;\nr01d9 <= r01d8;\nr02d1 <= r02;\nr02d2 <= r02d1;\nr02d3 <= r02d2;\nr02d4 <= r02d3;\nr02d5 <= r02d4;\nr02d6 <= r02d5;\nr02d7 <= r02d6;\nr02d8 <= r02d7;\nr02d9 <= r02d8;\nr03d1 <= r03;\nr03d2 <= r03d1;\nr03d3 <= r03d2;\nr03d4 <= r03d3;\nr03d5 <= r03d4;\nr03d6 <= r03d5;\nr03d7 <= r03d6;\nr03d8 <= r03d7;\nr03d9 <= r03d8;\nr04d1 <= r04;\nr04d2 <= r04d1;\nr04d3 <= r04d2;\nr04d4 <= r04d3;\nr04d5 <= r04d4;\nr04d6 <= r04d5;\nr04d7 <= r04d6;\nr04d8 <= r04d7;\nr04d9 <= r04d8;\nr05d1 <= r05;\nr05d2 <= r05d1;\nr05d3 <= r05d2;\nr05d4 <= r05d3;\nr05d5 <= r05d4;\nr05d6 <= r05d5;\nr05d7 <= r05d6;\nr05d8 <= r05d7;\nr05d9 <= r05d8;\nr06d1 <= r06;\nr06d2 <= r06d1;\nr06d3 <= r06d2;\nr06d4 <= r06d3;\nr06d5 <= r06d4;\nr06d6 <= r06d5;\nr06d7 <= r06d6;\nr06d8 <= r06d7;\nr06d9 <= r06d8;\nr07d1 <= r07;\nr07d2 <= r07d1;\nr07d3 <= r07d2;\nr07d4 <= r07d3;\nr07d5 <= r07d4;\nr07d6 <= r07d5;\nr07d7 <= r07d6;\nr07d8 <= r07d7;\nr07d9 <= r07d8;\nr08d1 <= r08;\nr08d2 <= r08d1;\nr08d3 <= r08d2;\nr08d4 <= r08d3;\nr08d5 <= r08d4;\nr08d6 <= r08d5;\nr08d7 <= r08d6;\nr08d8 <= r08d7;\nr08d9 <= r08d8;\nr09d1 <= r09;\nr09d2 <= r09d1;\nr09d3 <= r09d2;\nr09d4 <= r09d3;\nr09d5 <= r09d4;\nr09d6 <= r09d5;\nr09d7 <= r09d6;\nr09d8 <= r09d7;\nr09d9 <= r09d8;\nr10d1 <= r10;\nr10d2 <= r10d1;\nr10d3 <= r10d2;\nr10d4 <= r10d3;\nr10d5 <= r10d4;\nr10d6 <= r10d5;\nr10d7 <= r10d6;\nr10d8 <= r10d7;\nr10d9 <= r10d8;\nr11d1 <= r11;\nr11d2 <= r11d1;\nr11d3 <= r11d2;\nr11d4 <= r11d3;\nr11d5 <= r11d4;\nr11d6 <= r11d5;\nr11d7 <= r11d6;\nr11d8 <= r11d7;\nr11d9 <= r11d8;\nr12d1 <= r12;\nr12d2 <= r12d1;\nr12d3 <= r12d2;\nr12d4 <= r12d3;\nr12d5 <= r12d4;\nr12d6 <= r12d5;\nr12d7 <= r12d6;\nr12d8 <= r12d7;\nr12d9 <= r12d8;\nr13d1 <= r13;\nr13d2 <= r13d1;\nr13d3 <= r13d2;\nr13d4 <= r13d3;\nr13d5 <= r13d4;\nr13d6 <= r13d5;\nr13d7 <= r13d6;\nr13d8 <= r13d7;\nr13d9 <= r13d8;\nr14d1 <= r14;\nr14d2 <= r14d1;\nr14d3 <= r14d2;\nr14d4 <= r14d3;\nr14d5 <= r14d4;\nr14d6 <= r14d5;\nr14d7 <= r14d6;\nr14d8 <= r14d7;\nr14d9 <= r14d8;\nr15d1 <= r15;\nr15d2 <= r15d1;\nr15d3 <= r15d2;\nr15d4 <= r15d3;\nr15d5 <= r15d4;\nr15d6 <= r15d5;\nr15d7 <= r15d6;\nr15d8 <= r15d7;\nr15d9 <= r15d8;\nend\n"
  },
  {
    "path": "experimental/LX150-EIGHT-C/test_icarus.v",
    "content": "// Testbench for ltcminer_icarus.v\n\n`timescale 1ns/1ps\n\n`ifdef SIM\t\t\t\t\t// Avoids wrong top selected if included in ISE/PlanAhead sources\nmodule test_ltcminer ();\n\n\treg clk = 1'b0;\n\treg [31:0] cycle = 32'd0;\n\n\tinitial begin\n\t\tclk = 0;\n\t\t\n\t\twhile(1)\n\t\tbegin\n\t\t\t#5 clk = 1; #5 clk = 0;\n\t\tend\n\tend\n\n\talways @ (posedge clk)\n\tbegin\n\t\tcycle <= cycle + 32'd1;\n\tend\n\t\n\t// Running with default zero's for the data1..3 regs.\n\t// tx_hash=553a4b69b43913a61b42013ce210f713eaa7332e48cda1bdf3b93b10161d0876 at 187,990 nS and\n\t// final_hash (if SIM is defined) at 188,000 nS with golden_nonce_match flag NOT set since it is\n\t// not a diff=32 share. To test golden_nonce, just tweak the target eg 31'hffffffff will match everything\n\t\n\t// With serial input(at comm_clk_frequency=1_000_000), we get rx_done at t=70,220nS, however there is already a\n\t// PBKDF2_SHA256_80_128 loaded in Xbuf (for nonce=00000001). The first final_hash at 188,000 nS is corrupted as\n\t// the input data has changed from all 0's. The Xbuf starts salsa rom at t=188,000 but the nonce is incorrectly\n\t// taken from the newly loaded data so once salsa in complete it also generates a corrupt final_hash at ~362,000 nS.\n\t// Nonce is incremented then the newly loaded data starts PBKDF2_SHA256_80_128, so we must supply a nonce 1 less\n\t// than the expected golden_nonce. The correct PBKDF2_SHA256_80_128 is ready at ~ 197,000 nS. We get final_hash for\n\t// the corrupted work at ~362,000 nS then our required golden_nonce is at 536,180 nS.\n\t// This is only really a problem for simulation. With live hashing we just lose 2 nonces every time getwork is\n\t// loaded, which isn't a big deal.\n\t\t\n\twire RxD;\n\twire TxD;\n\twire extminer_rxd = 0;\n\twire extminer_txd;\n\twire [3:0] dip = 0;\n\twire [3:0] led;\n\twire TMP_SCL=1, TMP_SDA=1, TMP_ALERT=1;\n\t\n\tparameter comm_clk_frequency = 1_000_000;\t// Speeds up serial loading enormously rx_done is at t=70,220nS\n\tparameter baud_rate = 115_200;\n\t\n\tltcminer_icarus #(.comm_clk_frequency(comm_clk_frequency)) uut\n\t\t(clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\t// Send serial data - 84 bytes, matches on nonce 318f (included in data)\n\t// NB starting nonce is 381e NOT 381f (see note above)\n\t\n\t// NORMAL...\n\t// reg [671:0] data = 672'h000007ff0000318e7e71441b141fe951b2b0c7dfc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af75575618e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\n\t// DYNPLL...\n\treg [671:0] data = 672'h55aa07ff0000318e7e71441b141fe951b2b0c7dfc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af75575618e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\t\n\treg\t\t\tserial_send = 0;\n\twire\t\tserial_busy;\n\treg [31:0]\tdata_32 = 0;\n\treg [31:0]\tstart_cycle = 0;\n\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(baud_rate)) sertx (.clk(clk), .TxD(RxD), .send(serial_send), .busy(serial_busy), .word(data_32));\n\n\t// TUNE this according to comm_clk_frequency so we send a single getwork (else it gets overwritten with 0's)\n\t// parameter stop_cycle = 7020;\t\t// For comm_clk_frequency=1_000_000\n\tparameter stop_cycle = 0;\t\t\t// Use this to DISABLE sending data\n\talways @ (posedge clk)\n\tbegin\n\t\tserial_send <= 0;\t\t\t\t// Default\n\t\t// Send data every time tx goes idle (NB the !serial_send is to prevent serial_send\n\t\t// going high for two cycles since serial_busy arrives one cycle after serial_send)\n\t\tif (cycle > 5 && cycle < stop_cycle && !serial_busy && !serial_send)\n\t\tbegin\n\t\t\tserial_send <= 1;\n\t\t\tdata_32 <= data[671:640];\n\t\t\tdata <= { data[639:0], 32'd0 };\n\t\t\tstart_cycle <= cycle;\t\t// Remember each start cycle (makes debugging easier)\n\t\tend\n\tend\n\nendmodule\n`endif"
  },
  {
    "path": "experimental/LX150-EIGHT-C/xilinx_dpram.v",
    "content": "// xilinx_ram.v - inferring the ram seems to work fine\n\nmodule ram # ( parameter ADDRBITS=10 ) (\n\traddr,\n\twaddr,\n\tclock,\n\tdata,\n\twren,\n\tq);\n\n\tinput\t[ADDRBITS-1:0]  raddr;\n\tinput\t[ADDRBITS-1:0]  waddr;\n\tinput\t  clock;\n\tinput\t[255:0]  data;\n\tinput\t  wren;\n\toutput\t[255:0]  q;\n\n\t//synthesis attribute ram_style of store is block\n\treg [255:0] store [(2 << (ADDRBITS-1))-1:0];\n\treg[ADDRBITS-1:0] raddr_reg;\n\treg[ADDRBITS-1:0] waddr_reg;\n\t\n\talways @ (posedge clock)\n\tbegin\n\t\traddr_reg <= raddr;\n\t\t(* S = \"TRUE\" *) waddr_reg <= waddr;\t// Extra register on waddr (replaces wr_addr1_d externally) to see if it improves routing\n\t\tif (wren)\n\t\t\tstore[waddr_reg] <= data;\n\tend\n\t\n\tassign q = store[raddr_reg];\n\t\t\t\nendmodule"
  },
  {
    "path": "experimental/LX150-EIGHT-C/xilinx_dyn_pll.v",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 1995-2011 Xilinx, Inc.  All rights reserved.\n////////////////////////////////////////////////////////////////////////////////\n//   ____  ____ \n//  /   /\\/   / \n// /___/  \\  /    Vendor: Xilinx \n// \\   \\   \\/     Version : 13.1\n//  \\   \\         Application : xaw2verilog\n//  /   /         Filename : main_pll.v\n// /___/   /\\     Timestamp : 06/03/2011 01:58:13\n// \\   \\  /  \\ \n//  \\___\\/\\___\\ \n//\n//Command: xaw2verilog -st /home/teknohog/dcm2/ipcore_dir/./main_pll.xaw /home/teknohog/dcm2/ipcore_dir/./main_pll\n//Design Name: main_pll\n//Device: xc3s500e-4fg320\n//\n// Module main_pll\n// Generated by Xilinx Architecture Wizard\n// Written for synthesis tool: XST\n\n`timescale 1ns / 1ps\n\nmodule dyn_pll # (parameter SPEED_MHZ = 25 )\n\t(CLKIN_IN, \n\tCLKFX1_OUT, \n\tCLKFX2_OUT, \n\tCLKDV_OUT,\n\tDCM_SP_LOCKED_OUT,\n\tdcm_progclk,\n\tdcm_progdata,\n\tdcm_progen,\n\tdcm_reset,\n\tdcm_progdone,\n\tdcm_locked,\n\tdcm_status);\n\t\n\tinput CLKIN_IN;\n\twire CLKIN_IBUFG_OUT;\n\twire CLK0_OUT;\n\toutput CLKFX1_OUT;\n\toutput CLKFX2_OUT;\n\toutput CLKDV_OUT;\n\toutput DCM_SP_LOCKED_OUT;\n\n\tinput dcm_progclk;\n\tinput dcm_progdata;\n\tinput dcm_progen;\n\tinput dcm_reset;\n\toutput dcm_progdone;\n\toutput dcm_locked;\n\toutput [2:1] dcm_status;\n\t\n\twire CLKFB_IN;\n\twire CLKIN_IBUFG;\n\twire CLK0_BUF;\n\twire CLKFX1_BUF;\n\twire CLKFX2_BUF;\n\twire CLKDV_BUF;\n\twire GND_BIT;\n\twire dcm_progclk_buf;\n\n\tassign GND_BIT = 0;\n\tassign CLKIN_IBUFG_OUT = CLKIN_IBUFG;\n\tassign CLK0_OUT = CLKFB_IN;\n\t\n\tIBUFG  CLKIN_IBUFG_INST (.I(CLKIN_IN), \n\t\t.O(CLKIN_IBUFG));\n\tBUFG  CLK0_BUFG_INST (.I(CLK0_BUF), \n\t\t.O(CLKFB_IN));\n\tBUFG  CLKFX1_BUFG_INST (.I(CLKFX1_BUF), \n\t\t.O(CLKFX1_OUT));\n\tBUFG  CLKFX2_BUFG_INST (.I(CLKFX2_BUF), \n\t\t.O(CLKFX2_OUT));\n\tBUFG  CLKDV_BUFG_INST (.I(CLKDV_BUF), \n\t\t.O(CLKDV_OUT));\n\tBUFG  DCMPROGCLK_BUFG_INST (.I(dcm_progclk), \n\t\t.O(dcm_progclk_buf));\n\n\t// 100 MHZ osc gives fixed 50MHz CLKFX1, 12.5MHZ CLKDV\n\tDCM_SP #( .CLK_FEEDBACK(\"1X\"), .CLKDV_DIVIDE(8.0), .CLKFX_DIVIDE(8),\n\t\t.CLKFX_MULTIPLY(4), .CLKIN_DIVIDE_BY_2(\"FALSE\"), \n\t\t.CLKIN_PERIOD(10.000), .CLKOUT_PHASE_SHIFT(\"NONE\"), \n\t\t.DESKEW_ADJUST(\"SYSTEM_SYNCHRONOUS\"), .DFS_FREQUENCY_MODE(\"LOW\"), \n\t\t.DLL_FREQUENCY_MODE(\"LOW\"), .DUTY_CYCLE_CORRECTION(\"TRUE\"), \n\t\t.FACTORY_JF(16'hC080), .PHASE_SHIFT(0), .STARTUP_WAIT(\"FALSE\") ) \n\t\tDCM_SP_INST (.CLKFB(CLKFB_IN), \n\t\t.CLKIN(CLKIN_IBUFG), \n\t\t.DSSEN(GND_BIT), \n\t\t.PSCLK(GND_BIT), \n\t\t.PSEN(GND_BIT), \n\t\t.PSINCDEC(GND_BIT), \n\t\t.RST(GND_BIT), \n\t\t.CLKDV(CLKDV_BUF), \n\t\t.CLKFX(CLKFX1_BUF), \n\t\t.CLKFX180(), \n\t\t.CLK0(CLK0_BUF), \n\t\t.CLK2X(), \n\t\t.CLK2X180(), \n\t\t.CLK90(), \n\t\t.CLK180(), \n\t\t.CLK270(), \n\t\t.LOCKED(DCM_SP_LOCKED_OUT), \n\t\t.PSDONE(), \n\t\t.STATUS());\n\n\tDCM_CLKGEN #(\n\t\t.CLKFX_DIVIDE(100),\t\t\t// 100Mhz osc so gives steps of 1MHz\n\t\t.CLKFX_MULTIPLY(SPEED_MHZ),\n\t\t.CLKFXDV_DIVIDE(2),\t\t\t// Unused\n\t\t.CLKIN_PERIOD(10.0),\n\t\t.CLKFX_MD_MAX(0.000),\n\t\t.SPREAD_SPECTRUM(\"NONE\"),\n\t\t.STARTUP_WAIT(\"FALSE\")\n\t\t) \n\t\tDCM_CLKGEN_INST (\n\t\t.CLKIN(CLKIN_IBUFG),\n\t\t.CLKFX(CLKFX2_BUF),\n\t\t.FREEZEDCM(1'b0),\n\t\t.PROGCLK(dcm_progclk_buf),\n\t\t.PROGDATA(dcm_progdata),\n\t\t.PROGEN(dcm_progen),\n\t\t.PROGDONE(dcm_progdone),\n\t\t.LOCKED(dcm_locked),\n\t\t.STATUS(dcm_status),\n\t\t.RST(dcm_reset)\n\t\t);\n\nendmodule\n"
  },
  {
    "path": "experimental/LX150-SIXTYFOUR-A/dyn_pll_ctrl.v",
    "content": "module dyn_pll_ctrl # (parameter SPEED_MHZ = 25, parameter SPEED_LIMIT = 100, parameter SPEED_MIN = 25, parameter OSC_MHZ = 100)\n\t(clk,\n\tclk_valid,\n\tspeed_in,\n\tstart,\n\tprogclk,\n\tprogdata,\n\tprogen,\n\treset,\n\tlocked,\n\tstatus);\n\n\tinput clk;\t\t\t\t// NB Assumed to be 12.5MHz uart_clk\n\tinput clk_valid;\t\t// Drive from LOCKED output of first dcm (ie uart_clk valid)\n\tinput [7:0] speed_in;\n\tinput start;\n\toutput reg progclk = 0;\n\toutput reg progdata = 0;\n\toutput reg progen = 0;\n\toutput reg reset = 0;\n\tinput locked;\n\tinput [2:1] status;\n\n\t// NB spec says to use (dval-1) and (mval-1), but I don't think we need to be that accurate\n\t//    and this saves an adder. Feel free to amend it.\n\treg [23:0] watchdog = 0;\n\treg [7:0] state = 0;\n\treg [7:0] dval = OSC_MHZ;\t// Osc clock speed (hence mval scales in MHz)\n\treg [7:0] mval = SPEED_MHZ;\n\treg start_d1 = 0;\n\t\n\talways @ (posedge clk)\n\tbegin\n\t\tprogclk <= ~progclk;\n\t\tstart_d1 <= start;\n\t\treset <= 1'b0;\n\t\t\n\t\t// Watchdog is just using locked, perhaps also need | ~status[2]\n\t\tif (locked)\n\t\t\twatchdog <= 0;\n\t\telse\n\t\t\twatchdog <= watchdog + 1'b1;\n\t\t\n\t\tif (watchdog[23])\t\t// Approx 670mS at 12.5MHz - NB spec is 5ms to lock at >50MHz CLKIN (50ms at <50MHz CLKIN)\n\t\tbegin\t\t\t\t\t// but allow longer just in case\n\t\t\twatchdog <= 0;\n\t\t\treset <= 1'b1;\t\t// One cycle at 12.5MHz should suffice (requirment is 3 CLKIN at 100MHz)\n\t\tend\n\t\t\n\t\tif (~clk_valid)\t\t\t// Try not to run while clk is unstable\n\t\tbegin\n\t\t\tprogen <= 0;\n\t\t\tprogdata <= 0;\n\t\t\tstate <= 0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\n\t\t\t// The documentation is unclear as to whether the DCM loads data on positive or negative edge. The timing\n\t\t\t// diagram unhelpfully shows data changing on the positive edge, which could mean either its sampled on\n\t\t\t// negative, or it was clocked on positive! However the following (WRONGLY) says NEGATIVE ...\n\t\t\t// http://forums.xilinx.com/t5/Spartan-Family-FPGAs/Spartan6-DCM-CLKGEN-does-PROGCLK-have-a-maximum-period-minimum/td-p/175642\n\t\t\t// BUT this can lock up the DCM, positive clock seems more reliable (but it can still lock up for low values of M, eg 2).\n\t\t\t// Added SPEED_MIN to prevent this (and positive clock is correct, after looking at other implementations eg ztex/theseven)\n\t\t\n\t\t\tif ((start || start_d1) && state==0 && speed_in >= SPEED_MIN && speed_in <= SPEED_LIMIT && progclk==1)\t// positive clock\n\t\t\t// if ((start || start_d1) && state==0 && speed_in >= SPEED_MIN && speed_in <= SPEED_LIMIT && progclk==0)\t// negative clock\n\t\t\tbegin\n\t\t\t\tprogen <= 0;\n\t\t\t\tprogdata <= 0;\n\t\t\t\tmval <= speed_in;\n\t\t\t\tdval <= OSC_MHZ;\n\t\t\t\tstate <= 1;\n\t\t\tend\n\t\t\tif (state != 0)\n\t\t\t\tstate <= state + 1'd1;\n\t\t\tcase (state)\t\t// Even values to sync with progclk\n\t\t\t\t// Send D\n\t\t\t\t2: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\t\tprogdata <= 1;\n\t\t\t\tend\n\t\t\t\t4: begin\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t6,8,10,12,14,16,18,20: begin\n\t\t\t\t\tprogdata <= dval[0];\n\t\t\t\t\tdval[6:0] <= dval[7:1];\n\t\t\t\tend\n\t\t\t\t22: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t// Send M\n\t\t\t\t32: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\t\tprogdata <= 1;\n\t\t\t\tend\n\t\t\t\t36,38,40,42,44,46,48,50: begin\n\t\t\t\t\tprogdata <= mval[0];\n\t\t\t\t\tmval[6:0] <= mval[7:1];\n\t\t\t\tend\n\t\t\t\t52: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t// Send GO - NB 1 clock cycle\n\t\t\t\t62: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\tend\n\t\t\t\t64: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\tend\n\t\t\t\t// We should wait on progdone/locked, but just go straight back to idle\n\t\t\t\t254: begin\n\t\t\t\t\tstate <= 0;\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n\tend\nendmodule\n"
  },
  {
    "path": "experimental/LX150-SIXTYFOUR-A/ltcminer_icarus.ucf",
    "content": "# Based on https://github.com/ngzhang/Icarus/blob/master/FPGA_project/Src/fpgaminer_top.ucf\n\nNET \"hash_clk\" TNM_NET = \"hash_clk\";\nNET \"pbkdf_clk\" TNM_NET = \"pbkdf_clk\";\nNET \"uart_clk\" TNM_NET = \"uart_clk\";\n\n# 10MHz hash_clk (it may route better specifying a slightly slower clock)\nTIMESPEC TS_hash_clk = PERIOD \"hash_clk\" 10 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\n# 50MHz pbkdf_clk\nTIMESPEC TS_pbkdf_clk = PERIOD \"pbkdf_clk\" 50 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\n# 12.5MHz uart_clk\nTIMESPEC TS_uart_clk = PERIOD \"uart_clk\" 12.5 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\nNET \"osc_clk\" LOC = J1 | IOSTANDARD = LVCMOS33;\n\n# serial port receive & transmit\nNET \"RxD\" LOC = D1 | IOSTANDARD = LVCMOS33;\nNET \"TxD\" LOC = B1 | IOSTANDARD = LVCMOS33;\n\n# TTL level serial port: ja3 = rxd, ja2 = txd\nNET \"extminer_txd[0]\" LOC = D22 | IOSTANDARD = LVCMOS33;\nNET \"extminer_rxd[0]\" LOC = B22 | IOSTANDARD = LVCMOS33;\n\nNET \"led[0]\" LOC = A18 | IOSTANDARD = LVCMOS33;\nNET \"led[1]\" LOC = B18 | IOSTANDARD = LVCMOS33;\nNET \"led[2]\" LOC = A17 | IOSTANDARD = LVCMOS33;\nNET \"led[3]\" LOC = A16 | IOSTANDARD = LVCMOS33;\n\nNET \"dip[0]\" LOC = A4 | IOSTANDARD = LVCMOS33;\nNET \"dip[1]\" LOC = D6 | IOSTANDARD = LVCMOS33;\nNET \"dip[2]\" LOC = C6 | IOSTANDARD = LVCMOS33;\nNET \"dip[3]\" LOC = C8 | IOSTANDARD = LVCMOS33;\n\nNET \"TMP_SCL\" LOC = C1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_SDA\" LOC = E1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_ALERT\" LOC = C3 | IOSTANDARD = LVCMOS33 | PULLUP;\n"
  },
  {
    "path": "experimental/LX150-SIXTYFOUR-A/ltcminer_icarus.v",
    "content": "/* ltcminer_icarus.v copyright kramble 2013\n * Based on https://github.com/teknohog/Open-Source-FPGA-Bitcoin-Miner/tree/master/projects/Xilinx_cluster_cgminer\n * Hub code for a cluster of miners using async links\n * by teknohog\n */\n\n`include \"../../source/sha-256-functions.v\"\n`include \"../../source/sha256_transform.v\"\n// `include \"../../ICARUS-LX150/xilinx_pll.v\"\t// Only needed if not USE_DYN_PLL\n`include \"../../ICARUS-LX150/uart_receiver.v\"\n`include \"../../ICARUS-LX150/uart_transmitter.v\"\n`include \"../../ICARUS-LX150/serial.v\"\n`include \"../../ICARUS-LX150/serial_hub.v\"\n`include \"../../ICARUS-LX150/hub_core.v\"\n`include \"../../ICARUS-LX150/pwm_fade.v\"\n\nmodule ltcminer_icarus (osc_clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n// NB SPEED_MHZ resolution is 5MHz steps to keep pll divide ratio sensible. Change the divider in xilinx_pll.v if you\n// want other steps (1MHz is not sensible as it requires divide 100 which is not in the allowed range 1..32 for DCM_SP)\n// New dyn_pll has 1MHz resolution and can be changed by sending a specific getwork packet (uses top bytes of target)\n\n`define USE_DYN_PLL\t\t// Enable new dyn_pll\n\n`ifdef SPEED_MHZ\n\tparameter SPEED_MHZ = `SPEED_MHZ;\n`else\n\tparameter SPEED_MHZ = 40;\t\t\t\t\t\t// Default to slow, use dynamic config to ramp up in realtime\n`endif\n\n`ifdef SPEED_LIMIT\n\tparameter SPEED_LIMIT = `SPEED_LIMIT;\t\t\t// Fastest speed accepted by dyn_pll config\n`else\n\tparameter SPEED_LIMIT = 100;\t\t\t\t\t// Deliberately conservative, increase at own risk\n`endif\n\n`ifdef SPEED_MIN\n\tparameter SPEED_MIN = `SPEED_MIN;\t\t\t\t// Slowest speed accepted by dyn_pll config (CARE can lock up if too low)\n`else\n\tparameter SPEED_MIN = 10;\n`endif\n\n`ifdef SERIAL_CLK\n\tparameter comm_clk_frequency = `SERIAL_CLK;\n`else\n\tparameter comm_clk_frequency = 12_500_000;\t\t// 100MHz divide 8\n`endif\n\n`ifdef BAUD_RATE\n\tparameter BAUD_RATE = `BAUD_RATE;\n`else\n\tparameter BAUD_RATE = 115_200;\n`endif\n\n// kramble - nonce distribution is crude using top 4 bits of nonce so max LOCAL_MINERS = 8\n// teknohog's was more sophisticated, but requires modification of hashcore.v\n\n// Miners on the same FPGA with this hub\n`ifdef LOCAL_MINERS\n\tparameter LOCAL_MINERS = `LOCAL_MINERS;\n`else\n\tparameter LOCAL_MINERS = 1;\t\t\t\t\t\t// One to four cores (configures ADDRBITS automatically)\n`endif\n\n`ifdef ADDRBITS\n\tparameter ADDRBITS = `ADDRBITS;\t\t\t\t\t// Override for simulation or a quick ISE build (eg one 10 bit core)\n`else\n\tparameter ADDRBITS = 12 - clog2(LOCAL_MINERS);\t// Automatically selects largest RAM that will fit LX150\n`endif\n\n// kramble - nonce distribution only works for a single external port \n`ifdef EXT_PORTS\n\tparameter EXT_PORTS = `EXT_PORTS;\n`else\n\tparameter EXT_PORTS = 1;\n`endif\n\n\tlocalparam SLAVES = LOCAL_MINERS + EXT_PORTS;\n\n\tinput osc_clk;\n\twire hash_clk, uart_clk, pbkdf_clk;\n\n`ifdef USE_DYN_PLL\n\twire first_dcm_locked, dcm_progclk, dcm_progdata, dcm_progen, dcm_reset, dcm_progdone, dcm_locked;\n\twire [2:1] dcm_status;\n`endif\n\n`ifndef SIM\n\t`ifdef USE_DYN_PLL\n\t\tdyn_pll # (.SPEED_MHZ(SPEED_MHZ)) dyn_pll_blk\n\t\t\t(osc_clk, \n\t\t\tpbkdf_clk, \n\t\t\thash_clk, \n\t\t\tuart_clk,\n\t\t\tfirst_dcm_locked,\n\t\t\tdcm_progclk,\n\t\t\tdcm_progdata,\n\t\t\tdcm_progen,\n\t\t\tdcm_reset,\n\t\t\tdcm_progdone,\n\t\t\tdcm_locked,\n\t\t\tdcm_status);\n\t`else\n\t\tmain_pll # (.SPEED_MHZ(SPEED_MHZ)) pll_blk (.CLKIN_IN(osc_clk), .CLKFX_OUT(hash_clk), .CLKDV_OUT(uart_clk));\n\t\tassign pbkdf_clk = uart_clk;\n\t`endif\n`else\n\tassign hash_clk = osc_clk;\n\tassign uart_clk = osc_clk;\n\tassign pbkdf_clk = osc_clk;\n\t`ifdef USE_DYN_PLL\n\t\tassign first_dcm_locked = 1'b1;\n\t\tassign dcm_progdone = 1'b1;\n\t\tassign dcm_locked = 1'b1;\n\t\tassign dcm_status = 0;\n\t`endif\t\n`endif\n\n`ifdef USE_DYN_PLL\n\treg [7:0] dyn_pll_speed = SPEED_MHZ;\n\treg dyn_pll_start = 0;\n\tparameter OSC_MHZ = 100;\t\t// Clock oscillator (used for divider ratio)\n\tdyn_pll_ctrl # (.SPEED_MHZ(SPEED_MHZ), .SPEED_LIMIT(SPEED_LIMIT), .SPEED_MIN(SPEED_MIN), .OSC_MHZ(OSC_MHZ)) dyn_pll_ctrl_blk\n\t\t(uart_clk,\t\t\t// NB uses uart_clk as its just osc/8 and should always be valid\n\t\tfirst_dcm_locked,\t// ... but we check it anyway\n\t\tdyn_pll_speed,\n\t\tdyn_pll_start,\n\t\tdcm_progclk,\n\t\tdcm_progdata,\n\t\tdcm_progen,\n\t\tdcm_reset,\n\t\tdcm_locked,\n\t\tdcm_status);\n`endif\n      \n\tinput TMP_SCL, TMP_SDA, TMP_ALERT;\t// Unused but set to PULLUP so as to avoid turning on the HOT LED\n\t\t\t\t\t\t\t\t\t\t// TODO implement I2C protocol to talk to temperature sensor chip (TMP101?)\n\t\t\t\t\t\t\t\t\t\t// and drive FAN speed control output.\n\n\tinput [3:0]dip;\n\twire reset, nonce_chip;\n\tassign reset = dip[0];\t\t\t// Not used\n\tassign nonce_chip = dip[1];\t\t// Distinguishes between the two Icarus FPGA's\n\n\t// Work distribution is simply copying to all miners, so no logic\n\t// needed there, simply copy the RxD.\n\tinput\tRxD;\n\toutput\tTxD;\n\n\t// Results from the input buffers (in serial_hub.v) of each slave\n\twire [SLAVES*32-1:0]\tslave_nonces;\n\twire [SLAVES*32-1:0]\tslave_debug_sr;\n\twire [SLAVES-1:0]\t\tnew_nonces;\n\n\t// Using the same transmission code as individual miners from serial.v\n\twire\t\tserial_send;\n\twire\t\tserial_busy;\n\twire [31:0]\tgolden_nonce;\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) sertx (.clk(uart_clk), .TxD(TxD), .send(serial_send), .busy(serial_busy), .word(golden_nonce));\n\n\thub_core #(.SLAVES(SLAVES)) hc (.uart_clk(uart_clk), .new_nonces(new_nonces), .golden_nonce(golden_nonce), .serial_send(serial_send), .serial_busy(serial_busy), .slave_nonces(slave_nonces));\n\n\t// Common workdata input for local miners\n\twire [255:0]\tdata1, data2;\n\twire [127:0]\tdata3;\n\twire [31:0]\t\ttarget;\n\treg  [31:0]\t\ttargetreg = 32'h000007ff;\t// Start at sane value (overwritten by serial_receive)\n\twire\t\t\trx_done;\t\t// Signals hashcore to reset the nonce\n\t\t\t\t\t\t\t\t\t// NB in my implementation, it loads the nonce from data3 which should be fine as\n\t\t\t\t\t\t\t\t\t// this should be zero, but also supports testing using non-zero nonces.\n\n\t// Synchronise across clock domains from uart_clk to hash_clk\n\t// This probably looks amateurish (mea maxima culpa, novice verilogger at work), but should be OK\n\treg rx_done_toggle = 1'b0;\t\t// uart_clk domain\n\talways @ (posedge uart_clk)\n\t\trx_done_toggle <= rx_done_toggle ^ rx_done;\n\n\treg rx_done_toggle_d1 = 1'b0;\t// hash_clk domain\n\treg rx_done_toggle_d2 = 1'b0;\n\treg rx_done_toggle_d3 = 1'b0;\n\t\n\twire loadnonce;\n\tassign loadnonce = rx_done_toggle_d3 ^ rx_done_toggle_d2;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\trx_done_toggle_d1 <= rx_done_toggle;\n\t\trx_done_toggle_d2 <= rx_done_toggle_d1;\n\t\trx_done_toggle_d3 <= rx_done_toggle_d2;\n\t\tif (loadnonce)\n\t\t\ttargetreg <= target;\n\tend\n\t// End of clock domain sync\n\n\twire [31:0] mod_target;\n\n`ifdef USE_DYN_PLL\n\t// Top byte of target is clock multiplier, 2nd byte is validation (one's complement of clock multiplier)\n\t// These bytes are always zero in normal getwork, so we now hard code in mod_target and use them to set clock speed.\n\t// NB The pll controller is in uart_clk domain so use serial_receive signals directly\n\t// wire [7:0]invtarg;\t\t\t\t\t// Just checking the syntax in simulator, DELETE\n\t// assign invtarg = ~target[24:16];\n\talways @ (posedge uart_clk)\n\tbegin\n\t\tdyn_pll_start <= 0;\n\t\t// A sanity check to reduce the risk of speed being set to garbage\n\t\t// Top byte of target is speed, second byte MUST be its inverse, and neither must be zero (which also rules out all ones)\n\t\tif (rx_done && target[31:24] != dyn_pll_speed && target[31:24] != 0 && target[23:16] != 0 && target[31:24] == ~target[23:16])\n\t\t// if (rx_done && target[31:24] != dyn_pll_speed && target[31:24] != 0)\t// Simpler version for DEBUG, does no verification\n\t\tbegin\n\t\t\tdyn_pll_speed <= target[31:24];\n\t\t\tdyn_pll_start <= 1;\n\t\tend\n\tend\n\tassign mod_target = { 16'd0, targetreg[15:0] };\t// Ignore top two bytes\n`else\n\t// Its better to always hard-wire the 16 MSB to zero ... if comms noise sets these bits it completely de-syncs,\n\t// generating a continuous stream of golden_nonces overwhelming the python driver which can't then reset the target.\n\t// assign mod_target = targetreg;\t\t\t\t// Original 32 bit target\n\tassign mod_target = { 16'd0, targetreg[15:0] };\t// Ignore top two bytes\n`endif\n\t\n\tserial_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) serrx (.clk(uart_clk), .RxD(RxD), .data1(data1),\n\t\t\t\t\t\t.data2(data2), .data3(data3), .target(target), .rx_done(rx_done));\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\n\t// Local miners now directly connected\n\tgenerate\n\t\tgenvar i;\n\t\tfor (i = 0; i < LOCAL_MINERS; i = i + 1)\n\t\t// begin: for_local_miners ... too verbose, so...\n\t\tbegin: miners\n\t\t\twire [31:0] nonce_out;\t// Not used\n\t\t\twire [2:0] nonce_core = i;\n\t\t\twire gn_match;\n\t\t\twire salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift;\n\t\t\twire [SBITS-1:0] salsa_din;\n\t\t\twire [SBITS-1:0] salsa_dout;\n\t\t\twire [3:0] dummy;\t// So we can ignore top 4 bits of slave_debug_sr\n\n\t\t\t// Currently one pbkdfengine per salsaengine - TODO share the pbkdfengine for several salsaengines\n\t\t\tpbkdfengine #(.SBITS(SBITS)) P\n\t\t\t\t(.hash_clk(hash_clk), .pbkdf_clk(pbkdf_clk), .data1(data1), .data2(data2), .data3(data3), .target(mod_target),\n\t\t\t\t.nonce_msb({nonce_chip, nonce_core}), .nonce_out(nonce_out), .golden_nonce_out(slave_nonces[i*32+31:i*32]),\n\t\t\t\t.golden_nonce_match(gn_match), .loadnonce(loadnonce),\n\t\t\t\t.salsa_din(salsa_din), .salsa_dout(salsa_dout), .salsa_busy(salsa_busy), .salsa_result(salsa_result),\n\t\t\t\t.salsa_reset(salsa_reset), .salsa_start(salsa_start), .salsa_shift(salsa_shift));\n\n\t\t\tsalsaengine #(.ADDRBITS(ADDRBITS), .SBITS(SBITS)) S\n\t\t\t\t(.hash_clk(hash_clk), .reset(salsa_reset), .din(salsa_din), .dout(salsa_dout),\n\t\t\t\t.shift(salsa_shift), .start(salsa_start), .busy(salsa_busy), .result(salsa_result) );\n\t\t\t\t\t\n\t\t\t// Synchronise across clock domains from pbkdf_clk to uart_clk for: assign new_nonces[i] = gn_match;\n\t\t\treg gn_match_toggle = 1'b0;\t\t// hash_clk domain\n\t\t\talways @ (posedge pbkdf_clk)\n\t\t\t\tgn_match_toggle <= gn_match_toggle ^ gn_match;\n\n\t\t\treg gn_match_toggle_d1 = 1'b0;\t// uart_clk domain\n\t\t\treg gn_match_toggle_d2 = 1'b0;\n\t\t\treg gn_match_toggle_d3 = 1'b0;\n\n\t\t\tassign new_nonces[i] = gn_match_toggle_d3 ^ gn_match_toggle_d2;\n\n\t\t\talways @ (posedge uart_clk)\n\t\t\tbegin\n\t\t\t\tgn_match_toggle_d1 <= gn_match_toggle;\n\t\t\t\tgn_match_toggle_d2 <= gn_match_toggle_d1;\n\t\t\t\tgn_match_toggle_d3 <= gn_match_toggle_d2;\n\t\t\tend\n\t\t\t// End of clock domain sync\n\t\tend // for\n\tendgenerate\n\n\t// External miner ports, results appended to the same\n\t// slave_nonces/new_nonces as local ones\n\toutput [EXT_PORTS-1:0] extminer_txd;\n\tinput [EXT_PORTS-1:0]  extminer_rxd;\n\t// wire [EXT_PORTS-1:0]  extminer_rxd_debug = 1'b1;\t// DISABLE INPUT\n\tassign extminer_txd = {EXT_PORTS{RxD}};\n\n\tgenerate\n\t\tgenvar j;\n\t\tfor (j = LOCAL_MINERS; j < SLAVES; j = j + 1)\n\t\t// begin: for_ports ... too verbose, so ...\n\t\tbegin: ports\n\t\t\tslave_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) slrx (.clk(uart_clk), .RxD(extminer_rxd[j-LOCAL_MINERS]), .nonce(slave_nonces[j*32+31:j*32]), .new_nonce(new_nonces[j]));\n\t\tend\n\tendgenerate\n\n\toutput [3:0] led;\n\tassign led[1] = ~RxD;\n\t// assign led[2] = ~TxD;\n\t// assign led[3] = ~ (TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED - held low (the TMP pins are PULLUP, this is a fudge to\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// avoid warning about unused inputs)\n\t\n\tassign led[3] = ~first_dcm_locked | ~dcm_locked | dcm_status[2] | ~(TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED now dcm status\n\n`define FLASHCLOCK\t\t// Gives some feedback as the the actual clock speed\n\n`ifdef FLASHCLOCK\n\treg [26:0] hash_count = 0;\n\treg [3:0] sync_hash_count = 0;\n\talways @ (posedge uart_clk)\n\t\tif (rx_done)\n\t\t\tsync_hash_count[0] <= ~sync_hash_count[0];\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tsync_hash_count[3:1] <= sync_hash_count[2:0];\n\t\thash_count <= hash_count + 1'b1;\n\t\tif (sync_hash_count[3] != sync_hash_count[2])\n\t\t\thash_count <= 0;\n\tend\n\tassign led[2] = hash_count[26];\n`else\n\tassign led[2] = ~TxD;\n`endif\n\n\t// Light up only from locally found nonces, not ext_port results\n\tpwm_fade pf (.clk(uart_clk), .trigger(|new_nonces[LOCAL_MINERS-1:0]), .drive(led[0]));\n   \nendmodule\n"
  },
  {
    "path": "experimental/LX150-SIXTYFOUR-A/pbkdfengine.v",
    "content": "/* pbkdfengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`define ICARUS\t\t\t// Comment this out when using the altera virtual_wire interface in ltcminer.v\n\t\n`timescale 1ns/1ps\n\nmodule pbkdfengine\n\t(hash_clk, pbkdf_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce,\n\t\t\tsalsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift);\n\n\tinput hash_clk;\t\t\t// Just drives shift register\n\tinput pbkdf_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\n\toutput [31:0] nonce_out;\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] salsa_dout;\n\toutput [SBITS-1:0] salsa_din;\n\n\tinput salsa_busy, salsa_result;\t// NB hash_clk domain\n\toutput salsa_reset;\n\toutput salsa_start;\n\toutput reg salsa_shift = 1'b0;\t// NB hash_clk domain\n\n\treg [6:0]resetcycles = 5'd0;\n\treg reset = 1'b0;\n\tassign salsa_reset = reset;\t\t// Propagate reset to salsaengine\n\n`ifdef WANTCYCLICRESET\t\t\n\treg [23:0]cycresetcount = 24'd0;\n`endif\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\t// Hard code a 72 cycle reset (NB assumes THREADS=16 in salsaengine, else we need more)\n\t\t// NB hash_clk is faster than pbkdf_clk so the salsaengine will actually be initialised well before\n\t\t// this period ends, but keep to 72 for now as simulation uses equal pbkdf and salsa clock speeds.\n\t\tresetcycles <= resetcycles + 1'd1;\n\t\tif (resetcycles == 7'd0)\n\t\t\treset <= 1'b1;\n\t\tif (resetcycles == 7'd72)\n\t\tbegin\n\t\t\treset <= 1'b0;\n\t\t\tresetcycles <= 7'd72;\n\t\tend\n`ifdef WANTCYCLICRESET\t\t\n\t\t// Cyclical reset every 2_500_000 clocks to ensure salsa pipeline does not drift out of sync\n\t\t// This may be unneccessary if we reset every loadnonce\n\t\t// Actually it seems to do more harm than good, so disabled\n\t\tcycresetcount <= cycresetcount + 1'd1;\n\t\tif (cycresetcount == 2_500_000)\t// 10 per second at 25MHz (adjust as neccessary)\n\t\tbegin\n\t\t\tcycresetcount <= 24'd0;\n\t\t\tresetcycles <= 5'd0;\n\t\tend\n`endif\t\t\n\t\t// Reset on loadnonce (the hash results will be junk anyway since data changes, so no loss of shares)\n\t\tif (loadnonce)\n\t\t\tresetcycles <= 5'd0;\n\tend\n\t\n\t`ifndef ICARUS\n\treg [31:0] nonce_previous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\t`endif\n\n\t`ifndef NOMULTICORE\n\t`ifdef SIM\n\t\treg [27:0] nonce_cnt = 28'h318f;\t// Start point for simulation (NB also define SIM in serial.v)\n\t`else\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t`endif\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\tassign nonce_out = nonce;\n\n\treg [31:0] nonce_sr = 32'd0;\t\t// Nonce is shifted to salsaengine for storage/retrieval (hash_clk domain)\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\treg [2:0] nonce_wait = 3'd0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [2:0] blockcnt = 3'd0;\t\t// Takes values 1..5 for block iteration\n\treg [1023:0] Xbuf = 1024'd0;\t// Shared input/output buffer and shift register (hash_clk domain)\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\tassign salsa_din = Xbuf[1023:1024-SBITS];\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\t\n\t// MixOut is little-endian word format to match scrypt.c so convert back to big-endian\n\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] mix;\n\t\tassign mix = Xbuf[`IDX(i)];\t\t// NB MixOut now shares Xbuf since shifted in/out\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\n\t// Interface control. This should be OK provided the threads remain evenly spaced (hence we reset on loadnonce)\n\t\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\treg Clr_SMixOutRdy = 1'b0;\n\twire Clr_SMixInRdy;\n\twire Set_SMixOutRdy;\n\n\treg [4:0]salsa_busy_d = 0;\t\t\t// Sync to pbkdf_clk domain\n\treg [4:0]salsa_result_d = 0;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\t// Sync to pbkdf_clk domain\n\t\tsalsa_busy_d[0] <= salsa_busy;\n\t\tif (salsa_busy & ~ salsa_busy_d[0])\n\t\t\tsalsa_busy_d[1] <= ~ salsa_busy_d[1];\t\t// Toggle on busy going high\n\t\t\n\t\tsalsa_result_d[0] <= salsa_result;\n\t\tif (salsa_result & ~ salsa_result_d[0])\n\t\t\tsalsa_result_d[1] <= ~ salsa_result_d[1];\t// Toggle on result going high\n\tend\n\t\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tsalsa_busy_d[4:2] <= salsa_busy_d[3:1];\n\t\tsalsa_result_d[4:2] <= salsa_result_d[3:1];\n\t\t\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\t\t\t\n\t\t// CARE there is a race with Set_SMixInRdy, Clr_SMixOutRdy which are set in the FSM\n\t\t// Need to assert reset for several cycles to ensure consistency (acutally use 15 since salsaengine needs more)\n\t\tif (reset)\n\t\tbegin\t\t\t\t\t\t\t// Reset takes priority\n\t\t\tSMixInRdy_state <= 1'b0;\n\t\t\tSMixOutRdy_state <= 1'b0;\n\t\tend\n\tend\n\t\n\tassign Clr_SMixInRdy = SMixInRdy_state & (salsa_busy_d[3] ^ salsa_busy_d[4]);\t\t\t// Clear on transition to busy\n\t\n\tassign Set_SMixOutRdy = ~SMixOutRdy_state & (salsa_result_d[3] ^ salsa_result_d[4]);\t// Set on transition to result\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\tassign salsa_start = SMixInRdy;\n\t\t\n\t// Clock crossing flags for shift register control (span pbkdf_clk, hash_clk domains)\n\treg [3:0]Xbuf_load_request = 1'b0;\n\treg [3:0]shift_request =  1'b0;\n\treg [3:0]shift_acknowledge = 1'b0;\n\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz)\n\t\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_NONCE=22, S_SHIFT_IN=41, S_SHIFT_OUT=42,\t\t\t\t// Direction relative to salsa unit\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\treg start_output = 0;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\n\t\tshift_acknowledge[3:1] <= shift_acknowledge[2:0];\t// Clock crossing\n\n\t\t`ifdef ICARUS\n\t\tif (loadnonce)\t\t\t\t// Separate clock domains means comparison is unsafe\n\t\t`else\n\t\tif (loadnonce || (nonce_previous_load != data3[127:96]))\n\t\t`endif\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_previous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\t`ifndef ICARUS\n\t\t\tnonce_previous_load <= data3[127:96];\n\t\t\t`endif\n\t\tend\n\t\t\n\t\tif (reset == 1'b1)\n\t\tbegin\n\t\t\tstate <= S_IDLE;\n\t\t\tstart_output <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tif (SMixOutRdy & ~start_output)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\t// Request shifter to start\n\t\t\t\t\t\tstate <= S_SHIFT_OUT;\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (start_output ||\t// Process output\n\t\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'b0;\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\t\tblockcnt <= 3'd1;\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_sr : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\t\t\n\t\t\t\tS_B6: begin\n\t\t\t\t\t\tkhash <= tx_hash;\t\t// Save temporarily (for Xbuf)\n\n\t\t\t\t\t\tXbuf_load_request[0] <= ~Xbuf_load_request[0];\t// NB also loads nonce_sr\n\n\t\t\t\t\t\tif (blockcnt == 3'd5)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tnonce_wait <= 3'd7;\n\t\t\t\t\t\t\tstate <= S_NONCE;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_NONCE: begin\n\t\t\t\t\t\t// Need to delay a few clocks for Xbuf_load_request to complete\n\t\t\t\t\t\tnonce_wait <= nonce_wait - 1'd1;\n\t\t\t\t\t\tif (nonce_wait == 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 1'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 1'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\n\t\t\t\t\t\t\tstate <= S_SHIFT_IN;\n\t\t\t\t\t\tend\n\t\t\t\t\n\t\t\t\tend\n\t\t\t\tS_SHIFT_IN: begin\t\t\t\t\t\t\t// Shifting from PBKDF2_SHA256 to salsa\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tSet_SMixInRdy <= 1'd1;\t\t\t\t// Flag salsa to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_SHIFT_OUT: begin\t\t\t\t\t\t\t// Shifting from salsa to PBKDF2_SHA256\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'd1;\t\t\t\t// Flag self to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_sr;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (state==S_R18)\n\t\t$display (\"final_hash %x\\n\", tx_hash);\n`endif\n\tend\n\n\t// Shift register control - NB hash_clk domain\n\t\n\treg\t[10:0]shift_count = 11'd0;\t// hash_clk domain\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tif (reset)\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b0;\n\t\t\tshift_count <= 11'd0;\n\t\tend\n\n\t\t// Clock crossing logic\n\t\tXbuf_load_request[3:1] <= Xbuf_load_request[2:0];\n\t\tif (Xbuf_load_request[3] != Xbuf_load_request[2])\n\t\tbegin\n\t\t\t// Shift output into X buffer from MSB->LSB\n\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\tXbuf[1023:768] <= khash;\n\n\t\t\tnonce_sr <= nonce;\t// Loaded several times, but of no consequence\n\t\tend\n\t\t\n\t\tshift_request[3:1] <= shift_request[2:0];\n\t\tif (shift_request[3] != shift_request[2])\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b1;\n\t\tend\n\n\t\tif (salsa_shift)\n\t\tbegin\n\t\t\tshift_count <= shift_count + 1'b1;\n\t\t\tXbuf <= { Xbuf[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], salsa_dout };\n\t\tend\n\t\t\n\t\tif (shift_count == (1024+32)/SBITS-1)\n\t\tbegin\n\t\t\tshift_acknowledge[0] = ~shift_acknowledge[0];\n\t\t\tshift_count <= 0;\n\t\t\tsalsa_shift <= 0;\n\t\tend\n\tend\n\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(pbkdf_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\nendmodule"
  },
  {
    "path": "experimental/LX150-SIXTYFOUR-A/salsa_piped.v",
    "content": "/* salsa_piped.v ... fully registered salsa core (column and row results regs)\n*\n* Copyright (c) 2013 kramble\n* Derived from scrypt.c Copyright 2009 Colin Percival, 2011 ArtForz\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\nmodule salsa (clk, B, Bx, Bo, X0out, Xaddr);\n\n// Latency 9 clock cycles (4 col steps + 4 row + 1 sync), hence 4 salsa iterations in 36 cycles\n\ninput clk;\ninput [511:0]B;\ninput [511:0]Bx;\noutput [511:0]Bo;\t\t// Output is async\noutput [511:0]X0out;\t// Becomes new X0\noutput [9:0]Xaddr;\t\t// Address\n\nwire [9:0] xa1, xa2, xa3, xa4, ya1, ya2, ya3, ya4;\n\nreg [511:0]x1d1, x1d1a, x1d1b, x1d1c, x1d1d, x1d1e, x1d1f, x1d1g;\nreg [511:0]x1d2, x1d2a, x1d2b, x1d2c, x1d2d, x1d2e, x1d2f, x1d2g;\nreg [511:0]x1d3, x1d3a, x1d3b, x1d3c, x1d3d, x1d3e, x1d3f, x1d3g;\nreg [511:0]x1d4, x1d4a, x1d4b, x1d4c, x1d4d, x1d4e, x1d4f, x1d4g;\n\nreg [511:0]Xod1, Xod1a, Xod1b, Xod1c, Xod1d, Xod1e, Xod1f, Xod1g;\nreg [511:0]Xod2, Xod2a, Xod2b, Xod2c, Xod2d, Xod2e, Xod2f, Xod2g;\nreg [511:0]Xod3, Xod3a, Xod3b, Xod3c, Xod3d, Xod3e, Xod3f, Xod3g;\nreg [511:0]Xod4, Xod4a, Xod4b, Xod4c, Xod4d, Xod4e, Xod4f, X0out;\n\nreg [511:0]xxd1, xxd1a, xxd1b, xxd1c, xxd1d, xxd1e, xxd1f, xxd1g;\nreg [511:0]xxd2, xxd2a, xxd2b, xxd2c, xxd2d, xxd2e, xxd2f, xxd2g;\nreg [511:0]xxd3, xxd3a, xxd3b, xxd3c, xxd3d, xxd3e, xxd3f, xxd3g;\nreg [511:0]xxd4, xxd4a, xxd4b, xxd4c, xxd4d, xxd4e, xxd4f, xxd4g;\n\nreg [511:0]yyd1, yyd1a, yyd1b, yyd1c, yyd1d, yyd1e, yyd1f, yyd1g;\nreg [511:0]yyd2, yyd2a, yyd2b, yyd2c, yyd2d, yyd2e, yyd2f, yyd2g;\nreg [511:0]yyd3, yyd3a, yyd3b, yyd3c, yyd3d, yyd3e, yyd3f, yyd3g;\nreg [511:0]yyd4, yyd4a, yyd4b, yyd4c, yyd4d, yyd4e, yyd4f, yyd4g;\n\nwire [511:0]xx;\t\t\t// Initial xor\nwire [511:0]x1;\t\t\t// Salasa core outputs\nwire [511:0]x2;\nwire [511:0]x3;\nwire [511:0]xr;\nwire [511:0]Xo;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsax1 (clk, xx, x1, xa1);\nsalsa_core salsax2 (clk, x1, x2, xa2);\nsalsa_core salsax3 (clk, x2, x3, xa3);\nsalsa_core salsax4 (clk, x3, xr, xa4);\n\nwire [511:0]yy;\t\t\t// Initial xor\nwire [511:0]y1;\t\t\t// Salasa core outputs\nwire [511:0]y2;\nwire [511:0]y3;\nwire [511:0]yr;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsay1 (clk, yy, y1, ya1);\nsalsa_core salsay2 (clk, y1, y2, ya2);\nsalsa_core salsay3 (clk, y2, y3, ya3);\nsalsa_core salsay4 (clk, y3, yr, ya4);\n\nassign Xaddr = yyd4f[9:0] + ya4;\n\ngenvar i;\ngenerate\n\tfor (i = 0; i < 16; i = i + 1) begin : XX\n\t\t// Initial XOR. NB this adds to the propagation delay of the first salsa, may want register it.\n\t\tassign xx[`IDX(i)] = B[`IDX(i)] ^ Bx[`IDX(i)];\n\t\tassign Xo[`IDX(i)] = xxd4g[`IDX(i)] + xr[`IDX(i)];\n\t\tassign yy[`IDX(i)] = x1d4g[`IDX(i)] ^ Xo[`IDX(i)];\n\t\tassign Bo[`IDX(i)] = yyd4g[`IDX(i)] + yr[`IDX(i)];\t// Async output\n\tend\nendgenerate\n\nalways @ (posedge clk)\nbegin\n\tx1d1 <= Bx;\n\tx1d1a <= x1d1;\n\tx1d1b <= x1d1a;\n\tx1d1c <= x1d1b;\n\tx1d1d <= x1d1c;\n\tx1d1e <= x1d1d;\n\tx1d1f <= x1d1e;\n\tx1d1g <= x1d1f;\n\n\tx1d2 <= x1d1g;\n\tx1d2a <= x1d2;\n\tx1d2b <= x1d2a;\n\tx1d2c <= x1d2b;\n\tx1d2d <= x1d2c;\n\tx1d2e <= x1d2d;\n\tx1d2f <= x1d2e;\n\tx1d2g <= x1d2f;\n\n\tx1d3 <= x1d2g;\n\tx1d3a <= x1d3;\n\tx1d3b <= x1d3a;\n\tx1d3c <= x1d3b;\n\tx1d3d <= x1d3c;\n\tx1d3e <= x1d3d;\n\tx1d3f <= x1d3e;\n\tx1d3g <= x1d3f;\n\n\tx1d4 <= x1d3g;\n\tx1d4a <= x1d4;\n\tx1d4b <= x1d4a;\n\tx1d4c <= x1d4b;\n\tx1d4d <= x1d4c;\n\tx1d4e <= x1d4d;\n\tx1d4f <= x1d4e;\n\tx1d4g <= x1d4f;\n\n\tXod1 <= Xo;\n\tXod1a <= Xod1;\n\tXod1b <= Xod1a;\n\tXod1c <= Xod1b;\n\tXod1d <= Xod1c;\n\tXod1e <= Xod1d;\n\tXod1f <= Xod1e;\n\tXod1g <= Xod1f;\n\n\tXod2 <= Xod1g;\n\tXod2a <= Xod2;\n\tXod2b <= Xod2a;\n\tXod2c <= Xod2b;\n\tXod2d <= Xod2c;\n\tXod2e <= Xod2d;\n\tXod2f <= Xod2e;\n\tXod2g <= Xod2f;\n\n\tXod3 <= Xod2g;\n\tXod3a <= Xod3;\n\tXod3b <= Xod3a;\n\tXod3c <= Xod3b;\n\tXod3d <= Xod3c;\n\tXod3e <= Xod3d;\n\tXod3f <= Xod3e;\n\tXod3g <= Xod3f;\n\n\tXod4 <= Xod3g;\n\tXod4a <= Xod4;\n\tXod4b <= Xod4a;\n\tXod4c <= Xod4b;\n\tXod4d <= Xod4c;\n\tXod4e <= Xod4d;\n\tXod4f <= Xod4e;\n\tX0out <= Xod4f;\n\n\txxd1 <= xx;\n\txxd1a <= xxd1;\n\txxd1b <= xxd1a;\n\txxd1c <= xxd1b;\n\txxd1d <= xxd1c;\n\txxd1e <= xxd1d;\n\txxd1f <= xxd1e;\n\txxd1g <= xxd1f;\n\n\txxd2 <= xxd1g;\n\txxd2a <= xxd2;\n\txxd2b <= xxd2a;\n\txxd2c <= xxd2b;\n\txxd2d <= xxd2c;\n\txxd2e <= xxd2d;\n\txxd2f <= xxd2e;\n\txxd2g <= xxd2f;\n\n\txxd3 <= xxd2g;\n\txxd3a <= xxd3;\n\txxd3b <= xxd3a;\n\txxd3c <= xxd3b;\n\txxd3d <= xxd3c;\n\txxd3e <= xxd3d;\n\txxd3f <= xxd3e;\n\txxd3g <= xxd3f;\n\n\txxd4 <= xxd3g;\n\txxd4a <= xxd4;\n\txxd4b <= xxd4a;\n\txxd4c <= xxd4b;\n\txxd4d <= xxd4c;\n\txxd4e <= xxd4d;\n\txxd4f <= xxd4e;\n\txxd4g <= xxd4f;\n\n\tyyd1 <= yy;\n\tyyd1a <= yyd1;\n\tyyd1b <= yyd1a;\n\tyyd1c <= yyd1b;\n\tyyd1d <= yyd1c;\n\tyyd1e <= yyd1d;\n\tyyd1f <= yyd1e;\n\tyyd1g <= yyd1f;\n\n\tyyd2 <= yyd1g;\n\tyyd2a <= yyd2;\n\tyyd2b <= yyd2a;\n\tyyd2c <= yyd2b;\n\tyyd2d <= yyd2c;\n\tyyd2e <= yyd2d;\n\tyyd2f <= yyd2e;\n\tyyd2g <= yyd2f;\n\n\tyyd3 <= yyd2g;\n\tyyd3a <= yyd3;\n\tyyd3b <= yyd3a;\n\tyyd3c <= yyd3b;\n\tyyd3d <= yyd3c;\n\tyyd3e <= yyd3d;\n\tyyd3f <= yyd3e;\n\tyyd3g <= yyd3f;\n\n\tyyd4 <= yyd3g;\n\tyyd4a <= yyd4;\n\tyyd4b <= yyd4a;\n\tyyd4c <= yyd4b;\n\tyyd4d <= yyd4c;\n\tyyd4e <= yyd4d;\n\tyyd4f <= yyd4e;\n\tyyd4g <= yyd4f;\n\nend\n\nendmodule\n\nmodule salsa_core (clk, x, out, addr);\n\ninput clk;\ninput [511:0]x;\noutput [511:0]out;\noutput [9:0]addr;\n\n// This is clunky due to my lack of verilog skills but it works so elegance can come later\n// ... actually its now gotten quite ridiculous, see KLUDGE below\n\n// Aliases for inputs\n\nwire [31:0] x00;\nwire [31:0] x01;\nwire [31:0] x02;\nwire [31:0] x03;\nwire [31:0] x04;\nwire [31:0] x05;\nwire [31:0] x06;\nwire [31:0] x07;\nwire [31:0] x08;\nwire [31:0] x09;\nwire [31:0] x10;\nwire [31:0] x11;\nwire [31:0] x12;\nwire [31:0] x13;\nwire [31:0] x14;\nwire [31:0] x15;\n\nassign x00 = x[`IDX(0)];\nassign x01 = x[`IDX(1)];\nassign x02 = x[`IDX(2)];\nassign x03 = x[`IDX(3)];\nassign x04 = x[`IDX(4)];\nassign x05 = x[`IDX(5)];\nassign x06 = x[`IDX(6)];\nassign x07 = x[`IDX(7)];\nassign x08 = x[`IDX(8)];\nassign x09 = x[`IDX(9)];\nassign x10 = x[`IDX(10)];\nassign x11 = x[`IDX(11)];\nassign x12 = x[`IDX(12)];\nassign x13 = x[`IDX(13)];\nassign x14 = x[`IDX(14)];\nassign x15 = x[`IDX(15)];\n\n// Column & Row Results (yup, I wrote a program to generate these) ...\n// Not all of these are used, but let the synthesizer take care of that for now\n// TODO prune the unused ones, may be important with certain synth settings\n\n// BEGIN KLUDGE\n`include \"sgen.inc\"\t\t\t// .inc so it does not accidentally get compiled separately as .v\n// END KLUDGE\n\nwire [31:0]c00s;\t\t\t// Column sums\nwire [31:0]c01s;\nwire [31:0]c02s;\nwire [31:0]c03s;\nwire [31:0]c04s;\nwire [31:0]c05s;\nwire [31:0]c06s;\nwire [31:0]c07s;\nwire [31:0]c08s;\nwire [31:0]c09s;\nwire [31:0]c10s;\nwire [31:0]c11s;\nwire [31:0]c12s;\nwire [31:0]c13s;\nwire [31:0]c14s;\nwire [31:0]c15s;\n\nwire [31:0]r00s;\t\t\t// Row sums\nwire [31:0]r01s;\nwire [31:0]r02s;\nwire [31:0]r03s;\nwire [31:0]r04s;\nwire [31:0]r05s;\nwire [31:0]r06s;\nwire [31:0]r07s;\nwire [31:0]r08s;\nwire [31:0]r09s;\nwire [31:0]r10s;\nwire [31:0]r11s;\nwire [31:0]r12s;\nwire [31:0]r13s;\nwire [31:0]r14s;\nwire [31:0]r15s;\n\nwire [31:0]r00sx;\n\n/* From scrypt.c\n\n#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))\n\tfor (i = 0; i < 8; i += 2) {\n\t\t// Operate on columns\n\t\tx04 ^= R(x00+x12, 7);\tx09 ^= R(x05+x01, 7);\tx14 ^= R(x10+x06, 7);\tx03 ^= R(x15+x11, 7);\n\t\tx08 ^= R(x04+x00, 9);\tx13 ^= R(x09+x05, 9);\tx02 ^= R(x14+x10, 9);\tx07 ^= R(x03+x15, 9);\n\t\tx12 ^= R(x08+x04,13);\tx01 ^= R(x13+x09,13);\tx06 ^= R(x02+x14,13);\tx11 ^= R(x07+x03,13);\n\t\tx00 ^= R(x12+x08,18);\tx05 ^= R(x01+x13,18);\tx10 ^= R(x06+x02,18);\tx15 ^= R(x11+x07,18);\n\n\t\t// Operate on rows\n\t\tx01 ^= R(x00+x03, 7);\tx06 ^= R(x05+x04, 7);\tx11 ^= R(x10+x09, 7);\tx12 ^= R(x15+x14, 7);\n\t\tx02 ^= R(x01+x00, 9);\tx07 ^= R(x06+x05, 9);\tx08 ^= R(x11+x10, 9);\tx13 ^= R(x12+x15, 9);\n\t\tx03 ^= R(x02+x01,13);\tx04 ^= R(x07+x06,13);\tx09 ^= R(x08+x11,13);\tx14 ^= R(x13+x12,13);\n\t\tx00 ^= R(x03+x02,18);\tx05 ^= R(x04+x07,18);\tx10 ^= R(x09+x08,18);\tx15 ^= R(x14+x13,18);\n\t}\n*/\n\n// cols\n\nassign c04s = x00 + x12;\nassign c09s = x05 + x01;\nassign c14s = x10 + x06;\nassign c03s = x15 + x11;\n\nassign c08s = c04 + x00d1;\nassign c13s = c09 + x05d1;\nassign c02s = c14 + x10d1;\nassign c07s = c03 + x15d1;\n\nassign c12s = c08 + c04d1;\nassign c01s = c13 + c09d1;\nassign c06s = c02 + c14d1;\nassign c11s = c07 + c03d1;\n\nassign c00s = c12 + c08d1;\nassign c05s = c01 + c13d1;\nassign c10s = c06 + c02d1;\nassign c15s = c11 + c07d1;\n\n// rows\n\nassign r01s = c00 + c03d3;\nassign r06s = c05 + c04d3;\nassign r11s = c10 + c09d3;\nassign r12s = c15 + c14d3;\n\nassign r02s = r01 + c00d1;\nassign r07s = r06 + c05d1;\nassign r08s = r11 + c10d1;\nassign r13s = r12 + c15d1;\n\nassign r03s = r02 + r01d1;\nassign r04s = r07 + r06d1;\nassign r09s = r08 + r11d1;\nassign r14s = r13 + r12d1;\n\nassign r00s = r03 + r02d1;\nassign r05s = r04 + r07d1;\nassign r10s = r09 + r08d1;\nassign r15s = r14 + r13d1;\n\n// Hack to bring out address one cycle earlier\nassign r00sx = c00d3 ^ { r00s[13:0], r00s[31:14] };\nassign addr = r00sx[9:0];\n\nassign out = { r15, r14d1, r13d2, r12d3, r11d3, r10, r09d1, r08d2, r07d2, r06d3, r05, r04d1, r03d1, r02d2, r01d3, r00 };\n\nalways @ (posedge clk)\nbegin\n\tc04 <= x04 ^ { c04s[24:0], c04s[31:25] };\n\tc09 <= x09 ^ { c09s[24:0], c09s[31:25] };\n\tc14 <= x14 ^ { c14s[24:0], c14s[31:25] };\n\tc03 <= x03 ^ { c03s[24:0], c03s[31:25] };\n\n\tc08 <= x08d1 ^ { c08s[22:0], c08s[31:23] };\n\tc13 <= x13d1 ^ { c13s[22:0], c13s[31:23] };\n\tc02 <= x02d1 ^ { c02s[22:0], c02s[31:23] };\n\tc07 <= x07d1 ^ { c07s[22:0], c07s[31:23] };\n\n\tc12 <= x12d2 ^ { c12s[18:0], c12s[31:19] };\n\tc01 <= x01d2 ^ { c01s[18:0], c01s[31:19] };\n\tc06 <= x06d2 ^ { c06s[18:0], c06s[31:19] };\n\tc11 <= x11d2 ^ { c11s[18:0], c11s[31:19] };\n\n\tc00 <= x00d3 ^ { c00s[13:0], c00s[31:14] };\n\tc05 <= x05d3 ^ { c05s[13:0], c05s[31:14] };\n\tc10 <= x10d3 ^ { c10s[13:0], c10s[31:14] };\n\tc15 <= x15d3 ^ { c15s[13:0], c15s[31:14] };\n\n\tr01 <= c01d1 ^ { r01s[24:0], r01s[31:25] };\n\tr06 <= c06d1 ^ { r06s[24:0], r06s[31:25] };\n\tr11 <= c11d1 ^ { r11s[24:0], r11s[31:25] };\n\tr12 <= c12d1 ^ { r12s[24:0], r12s[31:25] };\n\n\tr02 <= c02d3 ^ { r02s[22:0], r02s[31:23] };\n\tr07 <= c07d3 ^ { r07s[22:0], r07s[31:23] };\n\tr08 <= c08d3 ^ { r08s[22:0], r08s[31:23] };\n\tr13 <= c13d3 ^ { r13s[22:0], r13s[31:23] };\n\n\tr03 <= c03d5 ^ { r03s[18:0], r03s[31:19] };\n\tr04 <= c04d5 ^ { r04s[18:0], r04s[31:19] };\n\tr09 <= c09d5 ^ { r09s[18:0], r09s[31:19] };\n\tr14 <= c14d5 ^ { r14s[18:0], r14s[31:19] };\n\n\t// r00 <= c00d3 ^ { r00s[13:0], r00s[31:14] };\n\tr00 <= r00sx;\n\tr05 <= c05d3 ^ { r05s[13:0], r05s[31:14] };\n\tr10 <= c10d3 ^ { r10s[13:0], r10s[31:14] };\n\tr15 <= c15d3 ^ { r15s[13:0], r15s[31:14] };\nend\nendmodule\n"
  },
  {
    "path": "experimental/LX150-SIXTYFOUR-A/salsaengine.v",
    "content": "/* salsaengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n// NB HALFRAM no longer applies, configure via parameters ADDRBITS, THREADS\n\n// Bracket this config option in SIM so we don't accidentally leave it set in a live build\n`ifdef SIM\n//`define ONETHREAD\t// Start one thread only (for SIMULATION less confusing and faster startup)\n`endif\n\n`timescale 1ns/1ps\n\nmodule salsaengine (hash_clk, reset, din, dout, shift, start, busy, result );\n\n\n\tinput hash_clk;\n\tinput reset;\t// NB pbkdf_clk domain (need a long reset (at least THREADS+4) to initialize correctly, this is done in pbkdfengine\n\tinput shift;\n\tinput start;\t// NB pbkdf_clk domain\n\toutput busy;\n\toutput reg result = 1'b0;\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] din;\n\toutput [SBITS-1:0] dout;\n\n\t// Configure ADDRBITS to allocate RAM for core (automatically sets LOOKAHEAD_GAP)\n\t// NB do not use ADDRBITS > 13 for THREADS=8 or ADDRBITS > 14 for THREADS=16 as this is more than\n\t// a full scratchpad and the calculation for INT_BITS will be invalid.\n\n\t// These settings are now overriden in ltcminer_icarus.v determined by LOCAL_MINERS ...\n\t// These values are for THREADS=8, scratchpad sizes are halved for THREADS=16\n\t// parameter ADDRBITS = 14;\t// 16MBit RAM allocated to core, full scratchpad for THREADS=16(will not fit LX150)\n\t// parameter ADDRBITS = 13;\t//  8MBit RAM allocated to core, full scratchpad (will not fit LX150)\n\tparameter ADDRBITS = 12;\t//  4MBit RAM allocated to core, half scratchpad\n\t// parameter ADDRBITS = 11;\t//  2MBit RAM allocated to core, quarter scratchpad\n\t// parameter ADDRBITS = 10;\t//  1MBit RAM allocated to core, eighth scratchpad\n\n\t// Do not change THREADS - this must match the salsa pipeline (8 or 16 cycle latency for 8 or 16 threads)\n\tparameter THREADS = 64;\t\t// NB Phase has THREADS+1 cycles\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n\tparameter THREADS_BITS = clog2(THREADS);\n\t\n\treg [THREADS_BITS:0]phase = 0;\n\treg [THREADS_BITS:0]phase_d = THREADS;\n\treg reset_d=0, fsmreset=0, start_d=0, fsmstart=0;\n\n\talways @ (posedge hash_clk)\t\t// Phase control and sync\n\tbegin\n\t\tphase <= (phase == THREADS) ? 0 : phase + 1;\n\t\tphase_d <= phase;\n\t\treset_d <= reset;\t\t\t// Synchronise to hash_clk domain\n\t\tfsmreset <= reset_d;\n\t\tstart_d <= start;\n\t\tfsmstart <= start_d;\n\tend\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\tparameter XSmix = 0, XSload = 1, XSram = 2;\t// One-hot since these map directly to mux contrls\n\n\treg [1:0] XCtl = XSmix;\n\n\tparameter R_IDLE=0, R_START=1, R_LOAD=2, R_WRITE=3, R_MIX=4, R_INT=5, R_WAIT=6;\n\treg [2:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs\n\treg addrwriteMix = 1'b0;\n\treg addrreadInit = 1'b0;\n\treg addrreadSave = 1'b0;\n\treg xoren = 1'b0;\n\n\t// NB This caclulation does NOT work for ADDRBITS>13 with THREADS=8 or ADDRBITS>14 with THREADS=16\n\tparameter INT_BITS = THREADS_BITS - ADDRBITS + 10;\t// Max intcycle value is 15 for THREADS=16 and ADDRBITS=10, needing 5 bits\n\t// Where INT_BITS==0 we have a full scratchpad and intcycles is not used (though a 1 bit reg[0:0] is still allocated)\n\tparameter INT_BITX = (INT_BITS > 0) ? INT_BITS : INT_BITS+1;\t// Workaround for compilation errors in unused code branches\n\n\treg [INT_BITS:0] intcycles = 0;\t\t\t\t\t\t// Number of interpolation cycles required\n\n\twire [511:0] Xmix;\n\treg [511:0] X0;\n\treg [511:0] X1;\n\twire [511:0] X0in;\n\twire [511:0] X1in;\n\twire [511:0] X0out;\n\treg [1023:0] salsaShiftReg;\n\treg [31:0] nonce_sr;\t\t\t// In series with salsaShiftReg\n\tassign dout = salsaShiftReg[1023:1024-SBITS];\n\n\t// sstate is implemented in ram (alternatively could use a rotating shift register)\n\treg [INT_BITS+28:0] sstate [THREADS-1:0];\t\t// NB initialized via a long reset (see pbkdfengine)\n\t// List components of sstate here for ease of maintenance ...\n\twire [2:0] mstate_in;\n\twire [10:0] cycle_in;\n\twire [9:0] writeaddr_in;\n\twire doneROM_in;\n\twire addrwriteMix_in;\n\twire addrreadInit_in;\n\twire addrreadSave_in;\n\twire [INT_BITS:0] intcycles_in;\n\n\twire [9:0] writeaddr_next = writeaddr_in + 10'd1;\n\n\treg [31:0] snonce [THREADS-1:0];\t\t\t\t\t// Nonce store. Note bidirectional loading below, this will either implement\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// as registers or dual-port ram, so do NOT integrate with sstate.\n\t\n\t// NB There is no busy_in or result_in as these flags are NOT saved on a per-thread basis\n\n\t// Convert salsaShiftReg to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = salsaShiftReg[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\tend\n\tendgenerate\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of RAM size\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\twire [9:0] Xaddr;\n\twire [ADDRBITS-1:0]rd_addr;\n\twire [ADDRBITS-1:0]wr_addr1;\n\twire [ADDRBITS-1:0]wr_addr2;\n\twire [ADDRBITS-1:0]wr_addr3;\n\twire [ADDRBITS-1:0]wr_addr4;\n\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\t(* S = \"TRUE\" *) reg ram_wren = 1'b0;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\t// Top ram address is reserved for X0Save/X1save, so adjust\n\t\n\twire [15:0] memtop = 16'hfffe;\t// One less than the top memory location (per THREAD bank)\n\t\n\twire [9-INT_BITS:0] adj_addr;\n\n\tif (INT_BITS > 0)\n\t\tassign adj_addr = (Xaddr[9:INT_BITS] == memtop[9:INT_BITS]) ?\n\t\t\t\t\t\t\tmemtop[9-INT_BITS:0] : Xaddr[9:INT_BITS];\n\telse\n\t\tassign adj_addr = Xaddr;\n\t\n\twire [THREADS_BITS-1:0] phase_addr;\t\t\t\t\t// Prefix for read address\n\tassign phase_addr = phase[THREADS_BITS-1:0];\n\treg [THREADS_BITS-1:0] phase_addr_d = 0;\t\t\t// Prefix for write address\n\n\tassign rd_addr = { phase_addr,\n\t\t\t\t\t\t(addrreadSave_in | addrreadInit_in) ?\n\t\t\t\t\t\t\t(addrreadInit_in ? {ADDRBITS-THREADS_BITS{1'b0}} : memtop[ADDRBITS-THREADS_BITS:1])\n\t\t\t\t\t\t:\n\t\t\t\t\t\t\tadj_addr };\n\t\t\n\twire [9:0] writeaddr_adj = addrwriteMix ? memtop[10:1] : writeaddr;\n\t\n\tassign wr_addr1 = { phase_addr_d, writeaddr_adj[9:INT_BITS] };\n\tassign wr_addr2 = { phase_addr_d, writeaddr_adj[9:INT_BITS] };\n\tassign wr_addr3 = { phase_addr_d, writeaddr_adj[9:INT_BITS] };\n\tassign wr_addr4 = { phase_addr_d, writeaddr_adj[9:INT_BITS] };\n\n\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_1 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_2 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_3 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_4 = 0;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr1 = rd_addr | rd_addr_z_1;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr2 = rd_addr | rd_addr_z_2;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr3 = rd_addr | rd_addr_z_3;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr4 = rd_addr | rd_addr_z_4;\n\t\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (rd_addr1, wr_addr1, ram_clk, ram1_din, ram_wren, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (rd_addr2, wr_addr2, ram_clk, ram2_din, ram_wren, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (rd_addr3, wr_addr3, ram_clk, ram3_din, ram_wren, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (rd_addr4, wr_addr4, ram_clk, ram4_din, ram_wren, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\n\t// Two ram data sources, the initial X value and the salsa output\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = XCtl[0] ? X : { Xmix, X0out};\t// Registered input\n\t\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, X0, X1, Xmix, X0out, Xaddr);\n\n\t// Main multiplexer\n\twire [511:0] Zbits;\n\tassign Zbits = {512{xoren}};\t\t// xoren enables xor from ram (else we load from ram)\n\t\n\t// XSMix is now the default and the initial load is now done via RAM to simplify the pipeline\n\tassign X0in =  XCtl[1] ? (X0out & Zbits) ^ ramout[511:0]    : X0out;\n\tassign X1in =  XCtl[1] ? (Xmix  & Zbits) ^ ramout[1023:512] : Xmix;\n\n\t// Salsa FSM - TODO may want to move this into a separate function (for floorplanning), see hashvariant-C\n\n\t// Hold separate state for each thread (a bit of a kludge to avoid rewriting FSM from scratch)\n\t// NB must ensure shift and result do NOT overlap by carefully controlling timing of start signal\n\t// NB Phase has THREADS+1 cycles, but we do not save the state for (phase==THREADS) as it is never active\n\n\tassign { mstate_in, writeaddr_in, cycle_in, doneROM_in, addrwriteMix_in, addrreadInit_in, addrreadSave_in, intcycles_in} =\n\t\t\t\t(phase == THREADS ) ? 0 : sstate[phase];\t\n\t\n\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\n\treg busy_flag = 1'b0;\n\t\n`ifdef ONETHREAD\n\t// TEST CONTROLLER ... just allow a single thread to run (busy is currently a common flag)\n\t// NB the thread automatically restarts after it completes, so its a slight misnomer to say it starts once.\n\treg start_once = 1'b0;\n\twire start_flag;\n\tassign start_flag = fsmstart & ~start_once;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine\n`else\n\t// NB start_flag only has effect when a thread is at R_IDLE, ie after reset, normally a thread will automatically\n\t// restart on completion. We need to spread the R_IDLE starts evenly to ensure proper ooperation. NB the pbkdf\n\t// engine requires busy and result, but this  looks alter itself in the salsa FSM, even though these are global\n\t// flags. Reset periodically (on loadnonce in pbkdfengine) to ensure it stays in sync.\n\treg [15:0] start_count = 0;\n\n\t// For THREADS=8, lookup_gap=2 salsa takes on average 9*(1024+(1024*1.5)) = 23040 clocks, generically 9*1024*(lookup_gap/2+1.5)\n\t// For THREADS=16, use 17*1024*(lookup_gap/2+1.5), where lookupgap is double that for THREADS=8\n\t// This is OK, but only does ADDRBITS=10,11,12 ...\n\t// parameter START_INTERVAL = (THREADS==16) ?\t((ADDRBITS==12) ? 60928 : (ADDRBITS==11) ? 95744 : 165376) / THREADS :\t// 16 threads\n\t//\t\t\t\t\t\t\t\t\t\t\t\t((ADDRBITS==12) ? 23040 : (ADDRBITS==11) ? 36864 :  50688) / THREADS ;\t//  8 threads\n\t// This seems to work OK generically (TODO check full scratchpad) ...\n\tparameter START_INTERVAL = (THREADS+1) * 1024 * ((1 << (15-ADDRBITS)) * THREADS / 32 + 3) / THREADS / 2;\n\n\treg start_flag = 1'b0;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine - this will toggle on transtion through R_START\n`endif\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tX0 <= X0in;\n\t\tX1 <= X1in;\n\t\t\n\t\tif (phase_d != THREADS)\n\t\t\tsstate[phase_d] <= fsmreset ? 0 : { mstate, writeaddr, cycle, doneROM, addrwriteMix, addrreadInit, addrreadSave, intcycles };\n\n\t\tmstate <= mstate_in;\t\t// Set defaults (overridden below as necessary)\n\t\twriteaddr <= writeaddr_in;\n\t\tcycle <= cycle_in;\n\t\tintcycles <= intcycles_in;\n\t\tdoneROM <= doneROM_in;\n\t\taddrwriteMix <= addrwriteMix_in;\n\t\taddrreadInit <= addrreadInit_in;\n\t\taddrreadSave <= addrreadSave_in;\t\t// Overwritten below, but addrreadSave_in is used above\n\t\t\n\t\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\trd_addr_z_1 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_2 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_3 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_4 <= {ADDRBITS{fsmreset}};\n\n\t\tphase_addr_d <= phase[THREADS_BITS-1:0];\n\t\t\n\t\tXCtl <= XSmix;\t\t\t\t// Default states\n\t\taddrreadInit <= 1'b0;\t\t// NB addrreadInit_in is the active control so this DOES need to be in sstate\n\t\taddrreadSave <= 1'b0;\t\t// Ditto\n\t\tram_wren <= 1'b0;\n\t\txoren <= 1'b1;\n\t\t\n\t\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\t\t`ifdef ONETHREAD\n\t\tif (fsmstart && phase!=THREADS)\n\t\t\tstart_once <= 1'b1;\n\t\tif (fsmreset)\n\t\t\tstart_once <= 1'b0;\n\t\t`else\n\t\tstart_count <= start_count + 1;\n\t\t// start_flag <= 1'b0;\t\t\t// Done below when we transition out of R_IDLE\n\t\tif (fsmreset || start_count == START_INTERVAL)\n\t\tbegin\n\t\t\tstart_count <= 0;\n\t\t\tif (~fsmreset && fsmstart)\n\t\t\t\tstart_flag <= 1'b1;\n\t\tend\n\t\t`endif\n\t\t\n\t\t// Could use explicit mux for this ...\n\t\tif (shift)\n\t\tbegin\n\t\t\tsalsaShiftReg <= { salsaShiftReg[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], din};\n\t\tend\n\t\telse\n\t\tif (XCtl[0] && phase_d != THREADS)\t\t// Set at end of previous hash - this is executed regardless of phase\t\t\n\t\tbegin\n\t\t\tsalsaShiftReg <= ramout;\t\t\t// Simultaneously with XSload\n\t\t\tnonce_sr <= snonce[phase_d];\t\t// NB bidirectional load\n\t\t\tsnonce[phase_d] <= nonce_sr;\n\t\tend\n\t\t\n\t\tif (fsmreset == 1'b1)\n\t\tbegin\n\t\t\tmstate <= R_IDLE;\t\t// This will propagate to all sstate slots as we hold reset for 10 cycles\n\t\t\tbusy_flag <= 1'b0;\n\t\t\tresult <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate_in)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\t// R_IDLE only applies after reset. Normally each thread will reenter at S_START and\n\t\t\t\t\t// assumes that input data is waiting (this relies on the threads being started evenly,\n\t\t\t\t\t// hence the interface FSM at the top of this file)\n\t\t\t\t\tif (phase!=THREADS && start_flag)\t// Ensure (phase==THREADS) slot is never active\n\t\t\t\t\tbegin\n\t\t\t\t\t\t`ifndef ONETHREAD\n\t\t\t\t\t\t\tstart_flag <= 1'b0;\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t\t// Toggle the busy flag low to ack pbkdfengine (its usually already set\n\t\t\t\t\t\t\t\t\t\t\t\t// since other threads are running)\n\t\t\t\t\t\tmstate <= R_START;\n\n\t\t\t\t\t\t// We cycle the initial data through the RAM to simplify the data path (costs 17 clocks)\n\t\t\t\t\t\t// Setup to write initial data to ram (on next clock)\n\t\t\t\t\t\twriteaddr <= 0;\n\t\t\t\t\t\taddrwriteMix <= 1'b0;\n\t\t\t\t\t\tram_wren <= 1'b1;\n\n\t\t\t\t\t\t// Setup to read initial data back from ram (17 clocks later)\n\t\t\t\t\t\tXCtl <= XSload;\n\t\t\t\t\t\taddrreadInit <= 1'b1;\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tR_START: begin\t\t\t\t\t// Reentry point after thread completion. ASSUMES new data is ready.\n\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\txoren <= 1'b0;\n\t\t\t\t\tcycle <= 0;\n\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\tbusy_flag <= 1'b1;\n\t\t\t\t\tresult <= 1'b0;\n\t\t\t\t\tmstate <= R_LOAD;\n\t\t\t\tend\n\n\t\t\t\tR_LOAD: begin\t\t\t\t\t// Now loading initial data via RAM to simplify data path (costs 17 clocks)\n\t\t\t\t\twriteaddr <= writeaddr_next;\n\t\t\t\t\tif (INT_BITS == 0)\n\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Full scratchpad needs to write to addr=001 next cycle\n\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\tend\n\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\twriteaddr <= writeaddr_next;\n\n\t\t\t\t\tif (writeaddr_in==1022)\n\t\t\t\t\t\tdoneROM <= 1'b1;\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\t\n\t\t\t\t\tif (doneROM_in)\n\t\t\t\t\tbegin\n\t\t\t\t\t\taddrwriteMix <= 1'b1;\t// Remains set for duration of R_MIX\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Load from ram next cycle (xor'd with XMix)\n\t\t\t\t\t\t// Need this to cover the case of the initial read being interpolated\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_MIX\n\t\t\t\t\t\tif (INT_BITS > 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { 1'b0, Xaddr[INT_BITX-1:0] };\t// Interpolated addresses\n\t\t\t\t\t\t\tif ( Xaddr[9:INT_BITX] ==  memtop[10-INT_BITX:1] )\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { 1'b1, Xaddr[INT_BITX-1:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:INT_BITX] == memtop[10-INT_BITX:1]) || |Xaddr[INT_BITX-1:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 1'b0;\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[INT_BITX-1:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:INT_BITX] ==  memtop[10-INT_BITX:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrreadSave <= 1'b1;\t\t// Preset to read saved data (17 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tram_wren <=\t(INT_BITS > 0) ? ~|writeaddr_next[INT_BITX-1:0] : 1'b1;\t\t\t\t\t\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\tcycle <= cycle_in + 11'd1;\n\t\t\t\t\tif (cycle_in==1023)\n\t\t\t\t\tbegin\n\t\t\t\t\t\t// We now ALWAYS write result to ram, thus simplifying the data path at the cost of 17 clock cycles\n\t\t\t\t\t\tmstate <= R_WAIT;\n\t\t\t\t\t\taddrreadSave <= 1'b1;\t\t// Preset to read saved data (17 clocks later)\n\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Save result\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle (xor'd with XMix)\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_WRITE\n\t\t\t\t\t\tif (INT_BITS > 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { 1'b0, Xaddr[INT_BITX-1:0] };\t\t\t// Interpolated addresses\n\t\t\t\t\t\t\tif ( Xaddr[9:INT_BITX] ==  memtop[10-INT_BITX:1] )\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { 1'b1, Xaddr[INT_BITX-1:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:INT_BITX] == memtop[10-INT_BITX:1]) || |Xaddr[INT_BITX-1:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 1'b0;\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[INT_BITX-1:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:INT_BITX] ==  memtop[10-INT_BITX:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrreadSave <= 1'b1;\t\t// Preset to read saved data (17 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tR_INT: begin\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\tintcycles <= intcycles_in - 1;\n\t\t\t\t\tif (intcycles_in==2)\n\t\t\t\t\t\taddrreadSave <= 1'b1;\t// Preset to read saved data (17 clocks later)\n\t\t\t\t\tif (intcycles_in==1)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Setup to XOR from saved X0/X1 in ram at next cycle\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\tend\n\t\t\t\t\t// Else mstate remains at R_INT so we continue interpolating\n\t\t\t\tend\n\n\t\t\t\tR_WAIT: begin\n\t\t\t\t\t\tif (fsmstart)\t\t\t// Check data input is ready\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\tbusy_flag <= 1'b0;\t\t// Will hold at 0 for 17 clocks until set at R_START\n\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\tmstate <= R_START;\t\t// Restart immediately\n\n\t\t\t\t\t\t\t// We cycle the initial data through the RAM to simplify the data path (costs 17 clocks)\n\t\t\t\t\t\t\t// Setup to write initial data to ram (on next clock)\n\t\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\t\taddrwriteMix <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t// Setup to read initial data back from ram (17 clocks later)\n\t\t\t\t\t\t\tXCtl <= XSload;\n\t\t\t\t\t\t\taddrreadInit <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\taddrreadSave <= 1'b1;\t\t// Preset to read saved data (17 clocks later)\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (mstate==R_MIX)\n\t\t$display (\"phase %d cycle %d Xmix %08x\\n\", phase, cycle-1, Xmix[511:480]);\n`endif\n\tend\t// always @(posedge hash_clk)\nendmodule"
  },
  {
    "path": "experimental/LX150-SIXTYFOUR-A/sgen.c",
    "content": "#include \"stdio.h\"\nint main()\n{\n\tint i; char c;\n\n\tfor (i=0; i<16; i++)\n\t\t\tprintf(\"reg [31:0] x%02dd1, x%02dd2, x%02dd3, x%02dd4, x%02dd5, x%02dd6, x%02dd7, x%02dd8, x%02dd9;\\n\",i,i,i,i,i,i,i,i,i);\n\t\t\t\n\tfor (i=0; i<16; i++)\n\t\t\tprintf(\"reg [31:0] c%02d, c%02dd1, c%02dd2, c%02dd3, c%02dd4, c%02dd5, c%02dd6, c%02dd7, c%02dd8, c%02dd9;\\n\",i,i,i,i,i,i,i,i,i,i);\n\n\tfor (i=0; i<16; i++)\n\t\t\tprintf(\"reg [31:0] r%02d, r%02dd1, r%02dd2, r%02dd3, r%02dd4, r%02dd5, r%02dd6, r%02dd7, r%02dd8, r%02dd9;\\n\",i,i,i,i,i,i,i,i,i,i);\n\n\tprintf(\"always @ (posedge clk)\\nbegin\\n\");\n\n\tc = 'x';\n\tfor (i=0; i<16; i++)\n\t{\n\t\tprintf (\"%c%02dd1 <= %c%02d;\\n\",  c, i, c, i);\n\t\tprintf (\"%c%02dd2 <= %c%02dd1;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd3 <= %c%02dd2;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd4 <= %c%02dd3;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd5 <= %c%02dd4;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd6 <= %c%02dd5;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd7 <= %c%02dd6;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd8 <= %c%02dd7;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd9 <= %c%02dd8;\\n\", c, i, c, i);\n\t}\n\t\n\tc = 'c';\n\tfor (i=0; i<16; i++)\n\t{\n\t\tprintf (\"%c%02dd1 <= %c%02d;\\n\",  c, i, c, i);\n\t\tprintf (\"%c%02dd2 <= %c%02dd1;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd3 <= %c%02dd2;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd4 <= %c%02dd3;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd5 <= %c%02dd4;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd6 <= %c%02dd5;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd7 <= %c%02dd6;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd8 <= %c%02dd7;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd9 <= %c%02dd8;\\n\", c, i, c, i);\n\t}\n\t\n\tc = 'r';\n\tfor (i=0; i<16; i++)\n\t{\n\t\tprintf (\"%c%02dd1 <= %c%02d;\\n\",  c, i, c, i);\n\t\tprintf (\"%c%02dd2 <= %c%02dd1;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd3 <= %c%02dd2;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd4 <= %c%02dd3;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd5 <= %c%02dd4;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd6 <= %c%02dd5;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd7 <= %c%02dd6;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd8 <= %c%02dd7;\\n\", c, i, c, i);\n\t\tprintf (\"%c%02dd9 <= %c%02dd8;\\n\", c, i, c, i);\n\t}\n\t\n\tprintf(\"end\\n\");\n\treturn 0;\n}\n"
  },
  {
    "path": "experimental/LX150-SIXTYFOUR-A/sgen.inc",
    "content": "reg [31:0] x00d1, x00d2, x00d3, x00d4, x00d5, x00d6, x00d7, x00d8, x00d9;\nreg [31:0] x01d1, x01d2, x01d3, x01d4, x01d5, x01d6, x01d7, x01d8, x01d9;\nreg [31:0] x02d1, x02d2, x02d3, x02d4, x02d5, x02d6, x02d7, x02d8, x02d9;\nreg [31:0] x03d1, x03d2, x03d3, x03d4, x03d5, x03d6, x03d7, x03d8, x03d9;\nreg [31:0] x04d1, x04d2, x04d3, x04d4, x04d5, x04d6, x04d7, x04d8, x04d9;\nreg [31:0] x05d1, x05d2, x05d3, x05d4, x05d5, x05d6, x05d7, x05d8, x05d9;\nreg [31:0] x06d1, x06d2, x06d3, x06d4, x06d5, x06d6, x06d7, x06d8, x06d9;\nreg [31:0] x07d1, x07d2, x07d3, x07d4, x07d5, x07d6, x07d7, x07d8, x07d9;\nreg [31:0] x08d1, x08d2, x08d3, x08d4, x08d5, x08d6, x08d7, x08d8, x08d9;\nreg [31:0] x09d1, x09d2, x09d3, x09d4, x09d5, x09d6, x09d7, x09d8, x09d9;\nreg [31:0] x10d1, x10d2, x10d3, x10d4, x10d5, x10d6, x10d7, x10d8, x10d9;\nreg [31:0] x11d1, x11d2, x11d3, x11d4, x11d5, x11d6, x11d7, x11d8, x11d9;\nreg [31:0] x12d1, x12d2, x12d3, x12d4, x12d5, x12d6, x12d7, x12d8, x12d9;\nreg [31:0] x13d1, x13d2, x13d3, x13d4, x13d5, x13d6, x13d7, x13d8, x13d9;\nreg [31:0] x14d1, x14d2, x14d3, x14d4, x14d5, x14d6, x14d7, x14d8, x14d9;\nreg [31:0] x15d1, x15d2, x15d3, x15d4, x15d5, x15d6, x15d7, x15d8, x15d9;\nreg [31:0] c00, c00d1, c00d2, c00d3, c00d4, c00d5, c00d6, c00d7, c00d8, c00d9;\nreg [31:0] c01, c01d1, c01d2, c01d3, c01d4, c01d5, c01d6, c01d7, c01d8, c01d9;\nreg [31:0] c02, c02d1, c02d2, c02d3, c02d4, c02d5, c02d6, c02d7, c02d8, c02d9;\nreg [31:0] c03, c03d1, c03d2, c03d3, c03d4, c03d5, c03d6, c03d7, c03d8, c03d9;\nreg [31:0] c04, c04d1, c04d2, c04d3, c04d4, c04d5, c04d6, c04d7, c04d8, c04d9;\nreg [31:0] c05, c05d1, c05d2, c05d3, c05d4, c05d5, c05d6, c05d7, c05d8, c05d9;\nreg [31:0] c06, c06d1, c06d2, c06d3, c06d4, c06d5, c06d6, c06d7, c06d8, c06d9;\nreg [31:0] c07, c07d1, c07d2, c07d3, c07d4, c07d5, c07d6, c07d7, c07d8, c07d9;\nreg [31:0] c08, c08d1, c08d2, c08d3, c08d4, c08d5, c08d6, c08d7, c08d8, c08d9;\nreg [31:0] c09, c09d1, c09d2, c09d3, c09d4, c09d5, c09d6, c09d7, c09d8, c09d9;\nreg [31:0] c10, c10d1, c10d2, c10d3, c10d4, c10d5, c10d6, c10d7, c10d8, c10d9;\nreg [31:0] c11, c11d1, c11d2, c11d3, c11d4, c11d5, c11d6, c11d7, c11d8, c11d9;\nreg [31:0] c12, c12d1, c12d2, c12d3, c12d4, c12d5, c12d6, c12d7, c12d8, c12d9;\nreg [31:0] c13, c13d1, c13d2, c13d3, c13d4, c13d5, c13d6, c13d7, c13d8, c13d9;\nreg [31:0] c14, c14d1, c14d2, c14d3, c14d4, c14d5, c14d6, c14d7, c14d8, c14d9;\nreg [31:0] c15, c15d1, c15d2, c15d3, c15d4, c15d5, c15d6, c15d7, c15d8, c15d9;\nreg [31:0] r00, r00d1, r00d2, r00d3, r00d4, r00d5, r00d6, r00d7, r00d8, r00d9;\nreg [31:0] r01, r01d1, r01d2, r01d3, r01d4, r01d5, r01d6, r01d7, r01d8, r01d9;\nreg [31:0] r02, r02d1, r02d2, r02d3, r02d4, r02d5, r02d6, r02d7, r02d8, r02d9;\nreg [31:0] r03, r03d1, r03d2, r03d3, r03d4, r03d5, r03d6, r03d7, r03d8, r03d9;\nreg [31:0] r04, r04d1, r04d2, r04d3, r04d4, r04d5, r04d6, r04d7, r04d8, r04d9;\nreg [31:0] r05, r05d1, r05d2, r05d3, r05d4, r05d5, r05d6, r05d7, r05d8, r05d9;\nreg [31:0] r06, r06d1, r06d2, r06d3, r06d4, r06d5, r06d6, r06d7, r06d8, r06d9;\nreg [31:0] r07, r07d1, r07d2, r07d3, r07d4, r07d5, r07d6, r07d7, r07d8, r07d9;\nreg [31:0] r08, r08d1, r08d2, r08d3, r08d4, r08d5, r08d6, r08d7, r08d8, r08d9;\nreg [31:0] r09, r09d1, r09d2, r09d3, r09d4, r09d5, r09d6, r09d7, r09d8, r09d9;\nreg [31:0] r10, r10d1, r10d2, r10d3, r10d4, r10d5, r10d6, r10d7, r10d8, r10d9;\nreg [31:0] r11, r11d1, r11d2, r11d3, r11d4, r11d5, r11d6, r11d7, r11d8, r11d9;\nreg [31:0] r12, r12d1, r12d2, r12d3, r12d4, r12d5, r12d6, r12d7, r12d8, r12d9;\nreg [31:0] r13, r13d1, r13d2, r13d3, r13d4, r13d5, r13d6, r13d7, r13d8, r13d9;\nreg [31:0] r14, r14d1, r14d2, r14d3, r14d4, r14d5, r14d6, r14d7, r14d8, r14d9;\nreg [31:0] r15, r15d1, r15d2, r15d3, r15d4, r15d5, r15d6, r15d7, r15d8, r15d9;\nalways @ (posedge clk)\nbegin\nx00d1 <= x00;\nx00d2 <= x00d1;\nx00d3 <= x00d2;\nx00d4 <= x00d3;\nx00d5 <= x00d4;\nx00d6 <= x00d5;\nx00d7 <= x00d6;\nx00d8 <= x00d7;\nx00d9 <= x00d8;\nx01d1 <= x01;\nx01d2 <= x01d1;\nx01d3 <= x01d2;\nx01d4 <= x01d3;\nx01d5 <= x01d4;\nx01d6 <= x01d5;\nx01d7 <= x01d6;\nx01d8 <= x01d7;\nx01d9 <= x01d8;\nx02d1 <= x02;\nx02d2 <= x02d1;\nx02d3 <= x02d2;\nx02d4 <= x02d3;\nx02d5 <= x02d4;\nx02d6 <= x02d5;\nx02d7 <= x02d6;\nx02d8 <= x02d7;\nx02d9 <= x02d8;\nx03d1 <= x03;\nx03d2 <= x03d1;\nx03d3 <= x03d2;\nx03d4 <= x03d3;\nx03d5 <= x03d4;\nx03d6 <= x03d5;\nx03d7 <= x03d6;\nx03d8 <= x03d7;\nx03d9 <= x03d8;\nx04d1 <= x04;\nx04d2 <= x04d1;\nx04d3 <= x04d2;\nx04d4 <= x04d3;\nx04d5 <= x04d4;\nx04d6 <= x04d5;\nx04d7 <= x04d6;\nx04d8 <= x04d7;\nx04d9 <= x04d8;\nx05d1 <= x05;\nx05d2 <= x05d1;\nx05d3 <= x05d2;\nx05d4 <= x05d3;\nx05d5 <= x05d4;\nx05d6 <= x05d5;\nx05d7 <= x05d6;\nx05d8 <= x05d7;\nx05d9 <= x05d8;\nx06d1 <= x06;\nx06d2 <= x06d1;\nx06d3 <= x06d2;\nx06d4 <= x06d3;\nx06d5 <= x06d4;\nx06d6 <= x06d5;\nx06d7 <= x06d6;\nx06d8 <= x06d7;\nx06d9 <= x06d8;\nx07d1 <= x07;\nx07d2 <= x07d1;\nx07d3 <= x07d2;\nx07d4 <= x07d3;\nx07d5 <= x07d4;\nx07d6 <= x07d5;\nx07d7 <= x07d6;\nx07d8 <= x07d7;\nx07d9 <= x07d8;\nx08d1 <= x08;\nx08d2 <= x08d1;\nx08d3 <= x08d2;\nx08d4 <= x08d3;\nx08d5 <= x08d4;\nx08d6 <= x08d5;\nx08d7 <= x08d6;\nx08d8 <= x08d7;\nx08d9 <= x08d8;\nx09d1 <= x09;\nx09d2 <= x09d1;\nx09d3 <= x09d2;\nx09d4 <= x09d3;\nx09d5 <= x09d4;\nx09d6 <= x09d5;\nx09d7 <= x09d6;\nx09d8 <= x09d7;\nx09d9 <= x09d8;\nx10d1 <= x10;\nx10d2 <= x10d1;\nx10d3 <= x10d2;\nx10d4 <= x10d3;\nx10d5 <= x10d4;\nx10d6 <= x10d5;\nx10d7 <= x10d6;\nx10d8 <= x10d7;\nx10d9 <= x10d8;\nx11d1 <= x11;\nx11d2 <= x11d1;\nx11d3 <= x11d2;\nx11d4 <= x11d3;\nx11d5 <= x11d4;\nx11d6 <= x11d5;\nx11d7 <= x11d6;\nx11d8 <= x11d7;\nx11d9 <= x11d8;\nx12d1 <= x12;\nx12d2 <= x12d1;\nx12d3 <= x12d2;\nx12d4 <= x12d3;\nx12d5 <= x12d4;\nx12d6 <= x12d5;\nx12d7 <= x12d6;\nx12d8 <= x12d7;\nx12d9 <= x12d8;\nx13d1 <= x13;\nx13d2 <= x13d1;\nx13d3 <= x13d2;\nx13d4 <= x13d3;\nx13d5 <= x13d4;\nx13d6 <= x13d5;\nx13d7 <= x13d6;\nx13d8 <= x13d7;\nx13d9 <= x13d8;\nx14d1 <= x14;\nx14d2 <= x14d1;\nx14d3 <= x14d2;\nx14d4 <= x14d3;\nx14d5 <= x14d4;\nx14d6 <= x14d5;\nx14d7 <= x14d6;\nx14d8 <= x14d7;\nx14d9 <= x14d8;\nx15d1 <= x15;\nx15d2 <= x15d1;\nx15d3 <= x15d2;\nx15d4 <= x15d3;\nx15d5 <= x15d4;\nx15d6 <= x15d5;\nx15d7 <= x15d6;\nx15d8 <= x15d7;\nx15d9 <= x15d8;\nc00d1 <= c00;\nc00d2 <= c00d1;\nc00d3 <= c00d2;\nc00d4 <= c00d3;\nc00d5 <= c00d4;\nc00d6 <= c00d5;\nc00d7 <= c00d6;\nc00d8 <= c00d7;\nc00d9 <= c00d8;\nc01d1 <= c01;\nc01d2 <= c01d1;\nc01d3 <= c01d2;\nc01d4 <= c01d3;\nc01d5 <= c01d4;\nc01d6 <= c01d5;\nc01d7 <= c01d6;\nc01d8 <= c01d7;\nc01d9 <= c01d8;\nc02d1 <= c02;\nc02d2 <= c02d1;\nc02d3 <= c02d2;\nc02d4 <= c02d3;\nc02d5 <= c02d4;\nc02d6 <= c02d5;\nc02d7 <= c02d6;\nc02d8 <= c02d7;\nc02d9 <= c02d8;\nc03d1 <= c03;\nc03d2 <= c03d1;\nc03d3 <= c03d2;\nc03d4 <= c03d3;\nc03d5 <= c03d4;\nc03d6 <= c03d5;\nc03d7 <= c03d6;\nc03d8 <= c03d7;\nc03d9 <= c03d8;\nc04d1 <= c04;\nc04d2 <= c04d1;\nc04d3 <= c04d2;\nc04d4 <= c04d3;\nc04d5 <= c04d4;\nc04d6 <= c04d5;\nc04d7 <= c04d6;\nc04d8 <= c04d7;\nc04d9 <= c04d8;\nc05d1 <= c05;\nc05d2 <= c05d1;\nc05d3 <= c05d2;\nc05d4 <= c05d3;\nc05d5 <= c05d4;\nc05d6 <= c05d5;\nc05d7 <= c05d6;\nc05d8 <= c05d7;\nc05d9 <= c05d8;\nc06d1 <= c06;\nc06d2 <= c06d1;\nc06d3 <= c06d2;\nc06d4 <= c06d3;\nc06d5 <= c06d4;\nc06d6 <= c06d5;\nc06d7 <= c06d6;\nc06d8 <= c06d7;\nc06d9 <= c06d8;\nc07d1 <= c07;\nc07d2 <= c07d1;\nc07d3 <= c07d2;\nc07d4 <= c07d3;\nc07d5 <= c07d4;\nc07d6 <= c07d5;\nc07d7 <= c07d6;\nc07d8 <= c07d7;\nc07d9 <= c07d8;\nc08d1 <= c08;\nc08d2 <= c08d1;\nc08d3 <= c08d2;\nc08d4 <= c08d3;\nc08d5 <= c08d4;\nc08d6 <= c08d5;\nc08d7 <= c08d6;\nc08d8 <= c08d7;\nc08d9 <= c08d8;\nc09d1 <= c09;\nc09d2 <= c09d1;\nc09d3 <= c09d2;\nc09d4 <= c09d3;\nc09d5 <= c09d4;\nc09d6 <= c09d5;\nc09d7 <= c09d6;\nc09d8 <= c09d7;\nc09d9 <= c09d8;\nc10d1 <= c10;\nc10d2 <= c10d1;\nc10d3 <= c10d2;\nc10d4 <= c10d3;\nc10d5 <= c10d4;\nc10d6 <= c10d5;\nc10d7 <= c10d6;\nc10d8 <= c10d7;\nc10d9 <= c10d8;\nc11d1 <= c11;\nc11d2 <= c11d1;\nc11d3 <= c11d2;\nc11d4 <= c11d3;\nc11d5 <= c11d4;\nc11d6 <= c11d5;\nc11d7 <= c11d6;\nc11d8 <= c11d7;\nc11d9 <= c11d8;\nc12d1 <= c12;\nc12d2 <= c12d1;\nc12d3 <= c12d2;\nc12d4 <= c12d3;\nc12d5 <= c12d4;\nc12d6 <= c12d5;\nc12d7 <= c12d6;\nc12d8 <= c12d7;\nc12d9 <= c12d8;\nc13d1 <= c13;\nc13d2 <= c13d1;\nc13d3 <= c13d2;\nc13d4 <= c13d3;\nc13d5 <= c13d4;\nc13d6 <= c13d5;\nc13d7 <= c13d6;\nc13d8 <= c13d7;\nc13d9 <= c13d8;\nc14d1 <= c14;\nc14d2 <= c14d1;\nc14d3 <= c14d2;\nc14d4 <= c14d3;\nc14d5 <= c14d4;\nc14d6 <= c14d5;\nc14d7 <= c14d6;\nc14d8 <= c14d7;\nc14d9 <= c14d8;\nc15d1 <= c15;\nc15d2 <= c15d1;\nc15d3 <= c15d2;\nc15d4 <= c15d3;\nc15d5 <= c15d4;\nc15d6 <= c15d5;\nc15d7 <= c15d6;\nc15d8 <= c15d7;\nc15d9 <= c15d8;\nr00d1 <= r00;\nr00d2 <= r00d1;\nr00d3 <= r00d2;\nr00d4 <= r00d3;\nr00d5 <= r00d4;\nr00d6 <= r00d5;\nr00d7 <= r00d6;\nr00d8 <= r00d7;\nr00d9 <= r00d8;\nr01d1 <= r01;\nr01d2 <= r01d1;\nr01d3 <= r01d2;\nr01d4 <= r01d3;\nr01d5 <= r01d4;\nr01d6 <= r01d5;\nr01d7 <= r01d6;\nr01d8 <= r01d7;\nr01d9 <= r01d8;\nr02d1 <= r02;\nr02d2 <= r02d1;\nr02d3 <= r02d2;\nr02d4 <= r02d3;\nr02d5 <= r02d4;\nr02d6 <= r02d5;\nr02d7 <= r02d6;\nr02d8 <= r02d7;\nr02d9 <= r02d8;\nr03d1 <= r03;\nr03d2 <= r03d1;\nr03d3 <= r03d2;\nr03d4 <= r03d3;\nr03d5 <= r03d4;\nr03d6 <= r03d5;\nr03d7 <= r03d6;\nr03d8 <= r03d7;\nr03d9 <= r03d8;\nr04d1 <= r04;\nr04d2 <= r04d1;\nr04d3 <= r04d2;\nr04d4 <= r04d3;\nr04d5 <= r04d4;\nr04d6 <= r04d5;\nr04d7 <= r04d6;\nr04d8 <= r04d7;\nr04d9 <= r04d8;\nr05d1 <= r05;\nr05d2 <= r05d1;\nr05d3 <= r05d2;\nr05d4 <= r05d3;\nr05d5 <= r05d4;\nr05d6 <= r05d5;\nr05d7 <= r05d6;\nr05d8 <= r05d7;\nr05d9 <= r05d8;\nr06d1 <= r06;\nr06d2 <= r06d1;\nr06d3 <= r06d2;\nr06d4 <= r06d3;\nr06d5 <= r06d4;\nr06d6 <= r06d5;\nr06d7 <= r06d6;\nr06d8 <= r06d7;\nr06d9 <= r06d8;\nr07d1 <= r07;\nr07d2 <= r07d1;\nr07d3 <= r07d2;\nr07d4 <= r07d3;\nr07d5 <= r07d4;\nr07d6 <= r07d5;\nr07d7 <= r07d6;\nr07d8 <= r07d7;\nr07d9 <= r07d8;\nr08d1 <= r08;\nr08d2 <= r08d1;\nr08d3 <= r08d2;\nr08d4 <= r08d3;\nr08d5 <= r08d4;\nr08d6 <= r08d5;\nr08d7 <= r08d6;\nr08d8 <= r08d7;\nr08d9 <= r08d8;\nr09d1 <= r09;\nr09d2 <= r09d1;\nr09d3 <= r09d2;\nr09d4 <= r09d3;\nr09d5 <= r09d4;\nr09d6 <= r09d5;\nr09d7 <= r09d6;\nr09d8 <= r09d7;\nr09d9 <= r09d8;\nr10d1 <= r10;\nr10d2 <= r10d1;\nr10d3 <= r10d2;\nr10d4 <= r10d3;\nr10d5 <= r10d4;\nr10d6 <= r10d5;\nr10d7 <= r10d6;\nr10d8 <= r10d7;\nr10d9 <= r10d8;\nr11d1 <= r11;\nr11d2 <= r11d1;\nr11d3 <= r11d2;\nr11d4 <= r11d3;\nr11d5 <= r11d4;\nr11d6 <= r11d5;\nr11d7 <= r11d6;\nr11d8 <= r11d7;\nr11d9 <= r11d8;\nr12d1 <= r12;\nr12d2 <= r12d1;\nr12d3 <= r12d2;\nr12d4 <= r12d3;\nr12d5 <= r12d4;\nr12d6 <= r12d5;\nr12d7 <= r12d6;\nr12d8 <= r12d7;\nr12d9 <= r12d8;\nr13d1 <= r13;\nr13d2 <= r13d1;\nr13d3 <= r13d2;\nr13d4 <= r13d3;\nr13d5 <= r13d4;\nr13d6 <= r13d5;\nr13d7 <= r13d6;\nr13d8 <= r13d7;\nr13d9 <= r13d8;\nr14d1 <= r14;\nr14d2 <= r14d1;\nr14d3 <= r14d2;\nr14d4 <= r14d3;\nr14d5 <= r14d4;\nr14d6 <= r14d5;\nr14d7 <= r14d6;\nr14d8 <= r14d7;\nr14d9 <= r14d8;\nr15d1 <= r15;\nr15d2 <= r15d1;\nr15d3 <= r15d2;\nr15d4 <= r15d3;\nr15d5 <= r15d4;\nr15d6 <= r15d5;\nr15d7 <= r15d6;\nr15d8 <= r15d7;\nr15d9 <= r15d8;\nend\n"
  },
  {
    "path": "experimental/LX150-SIXTYFOUR-A/test_icarus.v",
    "content": "// Testbench for ltcminer_icarus.v\n\n`timescale 1ns/1ps\n\n`ifdef SIM\t\t\t\t\t// Avoids wrong top selected if included in ISE/PlanAhead sources\nmodule test_ltcminer ();\n\n\treg clk = 1'b0;\n\treg [31:0] cycle = 32'd0;\n\n\tinitial begin\n\t\tclk = 0;\n\t\t\n\t\twhile(1)\n\t\tbegin\n\t\t\t#5 clk = 1; #5 clk = 0;\n\t\tend\n\tend\n\n\talways @ (posedge clk)\n\tbegin\n\t\tcycle <= cycle + 32'd1;\n\tend\n\t\n\t// Running with default zero's for the data1..3 regs.\n\t// tx_hash=553a4b69b43913a61b42013ce210f713eaa7332e48cda1bdf3b93b10161d0876 at 187,990 nS and\n\t// final_hash (if SIM is defined) at 188,000 nS with golden_nonce_match flag NOT set since it is\n\t// not a diff=32 share. To test golden_nonce, just tweak the target eg 31'hffffffff will match everything\n\t\n\t// With serial input(at comm_clk_frequency=1_000_000), we get rx_done at t=70,220nS, however there is already a\n\t// PBKDF2_SHA256_80_128 loaded in Xbuf (for nonce=00000001). The first final_hash at 188,000 nS is corrupted as\n\t// the input data has changed from all 0's. The Xbuf starts salsa rom at t=188,000 but the nonce is incorrectly\n\t// taken from the newly loaded data so once salsa in complete it also generates a corrupt final_hash at ~362,000 nS.\n\t// Nonce is incremented then the newly loaded data starts PBKDF2_SHA256_80_128, so we must supply a nonce 1 less\n\t// than the expected golden_nonce. The correct PBKDF2_SHA256_80_128 is ready at ~ 197,000 nS. We get final_hash for\n\t// the corrupted work at ~362,000 nS then our required golden_nonce is at 536,180 nS.\n\t// This is only really a problem for simulation. With live hashing we just lose 2 nonces every time getwork is\n\t// loaded, which isn't a big deal.\n\t\t\n\twire RxD;\n\twire TxD;\n\twire extminer_rxd = 0;\n\twire extminer_txd;\n\twire [3:0] dip = 0;\n\twire [3:0] led;\n\twire TMP_SCL=1, TMP_SDA=1, TMP_ALERT=1;\n\t\n\tparameter comm_clk_frequency = 1_000_000;\t// Speeds up serial loading enormously rx_done is at t=70,220nS\n\tparameter baud_rate = 115_200;\n\t\n\tltcminer_icarus #(.comm_clk_frequency(comm_clk_frequency)) uut\n\t\t(clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\t// Send serial data - 84 bytes, matches on nonce 318f (included in data)\n\t// NB starting nonce is 381e NOT 381f (see note above)\n\t\n\t// NORMAL...\n\t// reg [671:0] data = 672'h000007ff0000318e7e71441b141fe951b2b0c7dfc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af75575618e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\n\t// DYNPLL...\n\treg [671:0] data = 672'h55aa07ff0000318e7e71441b141fe951b2b0c7dfc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af75575618e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\t\n\treg\t\t\tserial_send = 0;\n\twire\t\tserial_busy;\n\treg [31:0]\tdata_32 = 0;\n\treg [31:0]\tstart_cycle = 0;\n\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(baud_rate)) sertx (.clk(clk), .TxD(RxD), .send(serial_send), .busy(serial_busy), .word(data_32));\n\n\t// TUNE this according to comm_clk_frequency so we send a single getwork (else it gets overwritten with 0's)\n\t// parameter stop_cycle = 7020;\t\t// For comm_clk_frequency=1_000_000\n\tparameter stop_cycle = 0;\t\t\t// Use this to DISABLE sending data\n\talways @ (posedge clk)\n\tbegin\n\t\tserial_send <= 0;\t\t\t\t// Default\n\t\t// Send data every time tx goes idle (NB the !serial_send is to prevent serial_send\n\t\t// going high for two cycles since serial_busy arrives one cycle after serial_send)\n\t\tif (cycle > 5 && cycle < stop_cycle && !serial_busy && !serial_send)\n\t\tbegin\n\t\t\tserial_send <= 1;\n\t\t\tdata_32 <= data[671:640];\n\t\t\tdata <= { data[639:0], 32'd0 };\n\t\t\tstart_cycle <= cycle;\t\t// Remember each start cycle (makes debugging easier)\n\t\tend\n\tend\n\nendmodule\n`endif"
  },
  {
    "path": "experimental/LX150-SIXTYFOUR-A/xilinx_dpram.v",
    "content": "// xilinx_ram.v - inferring the ram seems to work fine\n\nmodule ram # ( parameter ADDRBITS=10 ) (\n\traddr,\n\twaddr,\n\tclock,\n\tdata,\n\twren,\n\tq);\n\n\tinput\t[ADDRBITS-1:0]  raddr;\n\tinput\t[ADDRBITS-1:0]  waddr;\n\tinput\t  clock;\n\tinput\t[255:0]  data;\n\tinput\t  wren;\n\toutput\t[255:0]  q;\n\n\t//synthesis attribute ram_style of store is block\n\treg [255:0] store [(2 << (ADDRBITS-1))-1:0];\n\treg[ADDRBITS-1:0] raddr_reg;\n\t\n\talways @ (posedge clock)\n\tbegin\n\t\traddr_reg <= raddr;\n\t\tif (wren)\n\t\t\tstore[waddr] <= data;\n\tend\n\t\n\tassign q = store[raddr_reg];\n\t\t\t\nendmodule"
  },
  {
    "path": "experimental/LX150-SIXTYFOUR-A/xilinx_dyn_pll.v",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 1995-2011 Xilinx, Inc.  All rights reserved.\n////////////////////////////////////////////////////////////////////////////////\n//   ____  ____ \n//  /   /\\/   / \n// /___/  \\  /    Vendor: Xilinx \n// \\   \\   \\/     Version : 13.1\n//  \\   \\         Application : xaw2verilog\n//  /   /         Filename : main_pll.v\n// /___/   /\\     Timestamp : 06/03/2011 01:58:13\n// \\   \\  /  \\ \n//  \\___\\/\\___\\ \n//\n//Command: xaw2verilog -st /home/teknohog/dcm2/ipcore_dir/./main_pll.xaw /home/teknohog/dcm2/ipcore_dir/./main_pll\n//Design Name: main_pll\n//Device: xc3s500e-4fg320\n//\n// Module main_pll\n// Generated by Xilinx Architecture Wizard\n// Written for synthesis tool: XST\n\n`timescale 1ns / 1ps\n\nmodule dyn_pll # (parameter SPEED_MHZ = 25 )\n\t(CLKIN_IN, \n\tCLKFX1_OUT, \n\tCLKFX2_OUT, \n\tCLKDV_OUT,\n\tDCM_SP_LOCKED_OUT,\n\tdcm_progclk,\n\tdcm_progdata,\n\tdcm_progen,\n\tdcm_reset,\n\tdcm_progdone,\n\tdcm_locked,\n\tdcm_status);\n\t\n\tinput CLKIN_IN;\n\twire CLKIN_IBUFG_OUT;\n\twire CLK0_OUT;\n\toutput CLKFX1_OUT;\n\toutput CLKFX2_OUT;\n\toutput CLKDV_OUT;\n\toutput DCM_SP_LOCKED_OUT;\n\n\tinput dcm_progclk;\n\tinput dcm_progdata;\n\tinput dcm_progen;\n\tinput dcm_reset;\n\toutput dcm_progdone;\n\toutput dcm_locked;\n\toutput [2:1] dcm_status;\n\t\n\twire CLKFB_IN;\n\twire CLKIN_IBUFG;\n\twire CLK0_BUF;\n\twire CLKFX1_BUF;\n\twire CLKFX2_BUF;\n\twire CLKDV_BUF;\n\twire GND_BIT;\n\twire dcm_progclk_buf;\n\n\tassign GND_BIT = 0;\n\tassign CLKIN_IBUFG_OUT = CLKIN_IBUFG;\n\tassign CLK0_OUT = CLKFB_IN;\n\t\n\tIBUFG  CLKIN_IBUFG_INST (.I(CLKIN_IN), \n\t\t.O(CLKIN_IBUFG));\n\tBUFG  CLK0_BUFG_INST (.I(CLK0_BUF), \n\t\t.O(CLKFB_IN));\n\tBUFG  CLKFX1_BUFG_INST (.I(CLKFX1_BUF), \n\t\t.O(CLKFX1_OUT));\n\tBUFG  CLKFX2_BUFG_INST (.I(CLKFX2_BUF), \n\t\t.O(CLKFX2_OUT));\n\tBUFG  CLKDV_BUFG_INST (.I(CLKDV_BUF), \n\t\t.O(CLKDV_OUT));\n\tBUFG  DCMPROGCLK_BUFG_INST (.I(dcm_progclk), \n\t\t.O(dcm_progclk_buf));\n\n\t// 100 MHZ osc gives fixed 50MHz CLKFX1, 12.5MHZ CLKDV\n\tDCM_SP #( .CLK_FEEDBACK(\"1X\"), .CLKDV_DIVIDE(8.0), .CLKFX_DIVIDE(8),\n\t\t.CLKFX_MULTIPLY(4), .CLKIN_DIVIDE_BY_2(\"FALSE\"), \n\t\t.CLKIN_PERIOD(10.000), .CLKOUT_PHASE_SHIFT(\"NONE\"), \n\t\t.DESKEW_ADJUST(\"SYSTEM_SYNCHRONOUS\"), .DFS_FREQUENCY_MODE(\"LOW\"), \n\t\t.DLL_FREQUENCY_MODE(\"LOW\"), .DUTY_CYCLE_CORRECTION(\"TRUE\"), \n\t\t.FACTORY_JF(16'hC080), .PHASE_SHIFT(0), .STARTUP_WAIT(\"FALSE\") ) \n\t\tDCM_SP_INST (.CLKFB(CLKFB_IN), \n\t\t.CLKIN(CLKIN_IBUFG), \n\t\t.DSSEN(GND_BIT), \n\t\t.PSCLK(GND_BIT), \n\t\t.PSEN(GND_BIT), \n\t\t.PSINCDEC(GND_BIT), \n\t\t.RST(GND_BIT), \n\t\t.CLKDV(CLKDV_BUF), \n\t\t.CLKFX(CLKFX1_BUF), \n\t\t.CLKFX180(), \n\t\t.CLK0(CLK0_BUF), \n\t\t.CLK2X(), \n\t\t.CLK2X180(), \n\t\t.CLK90(), \n\t\t.CLK180(), \n\t\t.CLK270(), \n\t\t.LOCKED(DCM_SP_LOCKED_OUT), \n\t\t.PSDONE(), \n\t\t.STATUS());\n\n\tDCM_CLKGEN #(\n\t\t.CLKFX_DIVIDE(100),\t\t\t// 100Mhz osc so gives steps of 1MHz\n\t\t.CLKFX_MULTIPLY(SPEED_MHZ),\n\t\t.CLKFXDV_DIVIDE(2),\t\t\t// Unused\n\t\t.CLKIN_PERIOD(10.0),\n\t\t.CLKFX_MD_MAX(0.000),\n\t\t.SPREAD_SPECTRUM(\"NONE\"),\n\t\t.STARTUP_WAIT(\"FALSE\")\n\t\t) \n\t\tDCM_CLKGEN_INST (\n\t\t.CLKIN(CLKIN_IBUFG),\n\t\t.CLKFX(CLKFX2_BUF),\n\t\t.FREEZEDCM(1'b0),\n\t\t.PROGCLK(dcm_progclk_buf),\n\t\t.PROGDATA(dcm_progdata),\n\t\t.PROGEN(dcm_progen),\n\t\t.PROGDONE(dcm_progdone),\n\t\t.LOCKED(dcm_locked),\n\t\t.STATUS(dcm_status),\n\t\t.RST(dcm_reset)\n\t\t);\n\nendmodule\n"
  },
  {
    "path": "experimental/LX150-SLOWEIGHT-A/dyn_pll_ctrl.v",
    "content": "module dyn_pll_ctrl # (parameter SPEED_MHZ = 25, parameter SPEED_LIMIT = 100, parameter SPEED_MIN = 25, parameter OSC_MHZ = 100)\n\t(clk,\n\tclk_valid,\n\tspeed_in,\n\tstart,\n\tprogclk,\n\tprogdata,\n\tprogen,\n\treset,\n\tlocked,\n\tstatus);\n\n\tinput clk;\t\t\t\t// NB Assumed to be 12.5MHz uart_clk\n\tinput clk_valid;\t\t// Drive from LOCKED output of first dcm (ie uart_clk valid)\n\tinput [7:0] speed_in;\n\tinput start;\n\toutput reg progclk = 0;\n\toutput reg progdata = 0;\n\toutput reg progen = 0;\n\toutput reg reset = 0;\n\tinput locked;\n\tinput [2:1] status;\n\n\t// NB spec says to use (dval-1) and (mval-1), but I don't think we need to be that accurate\n\t//    and this saves an adder. Feel free to amend it.\n\treg [23:0] watchdog = 0;\n\treg [7:0] state = 0;\n\treg [7:0] dval = OSC_MHZ;\t// Osc clock speed (hence mval scales in MHz)\n\treg [7:0] mval = SPEED_MHZ;\n\treg start_d1 = 0;\n\t\n\talways @ (posedge clk)\n\tbegin\n\t\tprogclk <= ~progclk;\n\t\tstart_d1 <= start;\n\t\treset <= 1'b0;\n\t\t\n\t\t// Watchdog is just using locked, perhaps also need | ~status[2]\n\t\tif (locked)\n\t\t\twatchdog <= 0;\n\t\telse\n\t\t\twatchdog <= watchdog + 1'b1;\n\t\t\n\t\tif (watchdog[23])\t\t// Approx 670mS at 12.5MHz - NB spec is 5ms to lock at >50MHz CLKIN (50ms at <50MHz CLKIN)\n\t\tbegin\t\t\t\t\t// but allow longer just in case\n\t\t\twatchdog <= 0;\n\t\t\treset <= 1'b1;\t\t// One cycle at 12.5MHz should suffice (requirment is 3 CLKIN at 100MHz)\n\t\tend\n\t\t\n\t\tif (~clk_valid)\t\t\t// Try not to run while clk is unstable\n\t\tbegin\n\t\t\tprogen <= 0;\n\t\t\tprogdata <= 0;\n\t\t\tstate <= 0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\n\t\t\t// The documentation is unclear as to whether the DCM loads data on positive or negative edge. The timing\n\t\t\t// diagram unhelpfully shows data changing on the positive edge, which could mean either its sampled on\n\t\t\t// negative, or it was clocked on positive! However the following (WRONGLY) says NEGATIVE ...\n\t\t\t// http://forums.xilinx.com/t5/Spartan-Family-FPGAs/Spartan6-DCM-CLKGEN-does-PROGCLK-have-a-maximum-period-minimum/td-p/175642\n\t\t\t// BUT this can lock up the DCM, positive clock seems more reliable (but it can still lock up for low values of M, eg 2).\n\t\t\t// Added SPEED_MIN to prevent this (and positive clock is correct, after looking at other implementations eg ztex/theseven)\n\t\t\n\t\t\tif ((start || start_d1) && state==0 && speed_in >= SPEED_MIN && speed_in <= SPEED_LIMIT && progclk==1)\t// positive clock\n\t\t\t// if ((start || start_d1) && state==0 && speed_in >= SPEED_MIN && speed_in <= SPEED_LIMIT && progclk==0)\t// negative clock\n\t\t\tbegin\n\t\t\t\tprogen <= 0;\n\t\t\t\tprogdata <= 0;\n\t\t\t\tmval <= speed_in;\n\t\t\t\tdval <= OSC_MHZ;\n\t\t\t\tstate <= 1;\n\t\t\tend\n\t\t\tif (state != 0)\n\t\t\t\tstate <= state + 1'd1;\n\t\t\tcase (state)\t\t// Even values to sync with progclk\n\t\t\t\t// Send D\n\t\t\t\t2: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\t\tprogdata <= 1;\n\t\t\t\tend\n\t\t\t\t4: begin\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t6,8,10,12,14,16,18,20: begin\n\t\t\t\t\tprogdata <= dval[0];\n\t\t\t\t\tdval[6:0] <= dval[7:1];\n\t\t\t\tend\n\t\t\t\t22: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t// Send M\n\t\t\t\t32: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\t\tprogdata <= 1;\n\t\t\t\tend\n\t\t\t\t36,38,40,42,44,46,48,50: begin\n\t\t\t\t\tprogdata <= mval[0];\n\t\t\t\t\tmval[6:0] <= mval[7:1];\n\t\t\t\tend\n\t\t\t\t52: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t// Send GO - NB 1 clock cycle\n\t\t\t\t62: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\tend\n\t\t\t\t64: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\tend\n\t\t\t\t// We should wait on progdone/locked, but just go straight back to idle\n\t\t\t\t254: begin\n\t\t\t\t\tstate <= 0;\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n\tend\nendmodule\n"
  },
  {
    "path": "experimental/LX150-SLOWEIGHT-A/ltcminer_icarus.ucf",
    "content": "# Based on https://github.com/ngzhang/Icarus/blob/master/FPGA_project/Src/fpgaminer_top.ucf\n\nNET \"hash_clk\" TNM_NET = \"hash_clk\";\nNET \"pbkdf_clk\" TNM_NET = \"pbkdf_clk\";\nNET \"uart_clk\" TNM_NET = \"uart_clk\";\n\n# 10MHz hash_clk (it may route better specifying a slightly slower clock)\nTIMESPEC TS_hash_clk = PERIOD \"hash_clk\" 10 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\n# 50MHz pbkdf_clk\nTIMESPEC TS_pbkdf_clk = PERIOD \"pbkdf_clk\" 50 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\n# 12.5MHz uart_clk\nTIMESPEC TS_uart_clk = PERIOD \"uart_clk\" 12.5 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\nNET \"osc_clk\" LOC = J1 | IOSTANDARD = LVCMOS33;\n\n# serial port receive & transmit\nNET \"RxD\" LOC = D1 | IOSTANDARD = LVCMOS33;\nNET \"TxD\" LOC = B1 | IOSTANDARD = LVCMOS33;\n\n# TTL level serial port: ja3 = rxd, ja2 = txd\nNET \"extminer_txd[0]\" LOC = D22 | IOSTANDARD = LVCMOS33;\nNET \"extminer_rxd[0]\" LOC = B22 | IOSTANDARD = LVCMOS33;\n\nNET \"led[0]\" LOC = A18 | IOSTANDARD = LVCMOS33;\nNET \"led[1]\" LOC = B18 | IOSTANDARD = LVCMOS33;\nNET \"led[2]\" LOC = A17 | IOSTANDARD = LVCMOS33;\nNET \"led[3]\" LOC = A16 | IOSTANDARD = LVCMOS33;\n\nNET \"dip[0]\" LOC = A4 | IOSTANDARD = LVCMOS33;\nNET \"dip[1]\" LOC = D6 | IOSTANDARD = LVCMOS33;\nNET \"dip[2]\" LOC = C6 | IOSTANDARD = LVCMOS33;\nNET \"dip[3]\" LOC = C8 | IOSTANDARD = LVCMOS33;\n\nNET \"TMP_SCL\" LOC = C1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_SDA\" LOC = E1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_ALERT\" LOC = C3 | IOSTANDARD = LVCMOS33 | PULLUP;\n"
  },
  {
    "path": "experimental/LX150-SLOWEIGHT-A/ltcminer_icarus.v",
    "content": "/* ltcminer_icarus.v copyright kramble 2013\n * Based on https://github.com/teknohog/Open-Source-FPGA-Bitcoin-Miner/tree/master/projects/Xilinx_cluster_cgminer\n * Hub code for a cluster of miners using async links\n * by teknohog\n */\n\n`include \"../../source/sha-256-functions.v\"\n`include \"../../source/sha256_transform.v\"\n// `include \"../../ICARUS-LX150/xilinx_pll.v\"\t// Only needed if not USE_DYN_PLL\n`include \"../../ICARUS-LX150/uart_receiver.v\"\n`include \"../../ICARUS-LX150/uart_transmitter.v\"\n`include \"../../ICARUS-LX150/serial.v\"\n`include \"../../ICARUS-LX150/serial_hub.v\"\n`include \"../../ICARUS-LX150/hub_core.v\"\n`include \"../../ICARUS-LX150/pwm_fade.v\"\n\nmodule ltcminer_icarus (osc_clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n// NB SPEED_MHZ resolution is 5MHz steps to keep pll divide ratio sensible. Change the divider in xilinx_pll.v if you\n// want other steps (1MHz is not sensible as it requires divide 100 which is not in the allowed range 1..32 for DCM_SP)\n// New dyn_pll has 1MHz resolution and can be changed by sending a specific getwork packet (uses top bytes of target)\n\n`define USE_DYN_PLL\t\t// Enable new dyn_pll\n\n`ifdef SPEED_MHZ\n\tparameter SPEED_MHZ = `SPEED_MHZ;\n`else\n\tparameter SPEED_MHZ = 25;\t\t\t\t\t\t// Default to slow, use dynamic config to ramp up in realtime\n`endif\n\n`ifdef SPEED_LIMIT\n\tparameter SPEED_LIMIT = `SPEED_LIMIT;\t\t\t// Fastest speed accepted by dyn_pll config\n`else\n\tparameter SPEED_LIMIT = 100;\t\t\t\t\t// Deliberately conservative, increase at own risk\n`endif\n\n`ifdef SPEED_MIN\n\tparameter SPEED_MIN = `SPEED_MIN;\t\t\t\t// Slowest speed accepted by dyn_pll config (CARE can lock up if too low)\n`else\n\tparameter SPEED_MIN = 10;\n`endif\n\n`ifdef SERIAL_CLK\n\tparameter comm_clk_frequency = `SERIAL_CLK;\n`else\n\tparameter comm_clk_frequency = 12_500_000;\t\t// 100MHz divide 8\n`endif\n\n`ifdef BAUD_RATE\n\tparameter BAUD_RATE = `BAUD_RATE;\n`else\n\tparameter BAUD_RATE = 115_200;\n`endif\n\n// kramble - nonce distribution is crude using top 4 bits of nonce so max LOCAL_MINERS = 8\n// teknohog's was more sophisticated, but requires modification of hashcore.v\n\n// Miners on the same FPGA with this hub\n`ifdef LOCAL_MINERS\n\tparameter LOCAL_MINERS = `LOCAL_MINERS;\n`else\n\tparameter LOCAL_MINERS = 1;\t\t\t\t\t\t// One to four cores (configures ADDRBITS automatically)\n`endif\n\n`ifdef ADDRBITS\n\tparameter ADDRBITS = `ADDRBITS;\t\t\t\t\t// Override for simulation or a quick ISE build (eg one 10 bit core)\n`else\n\tparameter ADDRBITS = 12 - clog2(LOCAL_MINERS);\t// Automatically selects largest RAM that will fit LX150\n`endif\n\n// kramble - nonce distribution only works for a single external port \n`ifdef EXT_PORTS\n\tparameter EXT_PORTS = `EXT_PORTS;\n`else\n\tparameter EXT_PORTS = 1;\n`endif\n\n\tlocalparam SLAVES = LOCAL_MINERS + EXT_PORTS;\n\n\tinput osc_clk;\n\twire hash_clk, uart_clk, pbkdf_clk;\n\n`ifdef USE_DYN_PLL\n\twire first_dcm_locked, dcm_progclk, dcm_progdata, dcm_progen, dcm_reset, dcm_progdone, dcm_locked;\n\twire [2:1] dcm_status;\n`endif\n\n`ifndef SIM\n\t`ifdef USE_DYN_PLL\n\t\tdyn_pll # (.SPEED_MHZ(SPEED_MHZ)) dyn_pll_blk\n\t\t\t(osc_clk, \n\t\t\tpbkdf_clk, \n\t\t\thash_clk, \n\t\t\tuart_clk,\n\t\t\tfirst_dcm_locked,\n\t\t\tdcm_progclk,\n\t\t\tdcm_progdata,\n\t\t\tdcm_progen,\n\t\t\tdcm_reset,\n\t\t\tdcm_progdone,\n\t\t\tdcm_locked,\n\t\t\tdcm_status);\n\t`else\n\t\tmain_pll # (.SPEED_MHZ(SPEED_MHZ)) pll_blk (.CLKIN_IN(osc_clk), .CLKFX_OUT(hash_clk), .CLKDV_OUT(uart_clk));\n\t\tassign pbkdf_clk = uart_clk;\n\t`endif\n`else\n\tassign hash_clk = osc_clk;\n\tassign uart_clk = osc_clk;\n\tassign pbkdf_clk = osc_clk;\n\t`ifdef USE_DYN_PLL\n\t\tassign first_dcm_locked = 1'b1;\n\t\tassign dcm_progdone = 1'b1;\n\t\tassign dcm_locked = 1'b1;\n\t\tassign dcm_status = 0;\n\t`endif\t\n`endif\n\n`ifdef USE_DYN_PLL\n\treg [7:0] dyn_pll_speed = SPEED_MHZ;\n\treg dyn_pll_start = 0;\n\tparameter OSC_MHZ = 100;\t\t// Clock oscillator (used for divider ratio)\n\tdyn_pll_ctrl # (.SPEED_MHZ(SPEED_MHZ), .SPEED_LIMIT(SPEED_LIMIT), .SPEED_MIN(SPEED_MIN), .OSC_MHZ(OSC_MHZ)) dyn_pll_ctrl_blk\n\t\t(uart_clk,\t\t\t// NB uses uart_clk as its just osc/8 and should always be valid\n\t\tfirst_dcm_locked,\t// ... but we check it anyway\n\t\tdyn_pll_speed,\n\t\tdyn_pll_start,\n\t\tdcm_progclk,\n\t\tdcm_progdata,\n\t\tdcm_progen,\n\t\tdcm_reset,\n\t\tdcm_locked,\n\t\tdcm_status);\n`endif\n      \n\tinput TMP_SCL, TMP_SDA, TMP_ALERT;\t// Unused but set to PULLUP so as to avoid turning on the HOT LED\n\t\t\t\t\t\t\t\t\t\t// TODO implement I2C protocol to talk to temperature sensor chip (TMP101?)\n\t\t\t\t\t\t\t\t\t\t// and drive FAN speed control output.\n\n\tinput [3:0]dip;\n\twire reset, nonce_chip;\n\tassign reset = dip[0];\t\t\t// Not used\n\tassign nonce_chip = dip[1];\t\t// Distinguishes between the two Icarus FPGA's\n\n\t// Work distribution is simply copying to all miners, so no logic\n\t// needed there, simply copy the RxD.\n\tinput\tRxD;\n\toutput\tTxD;\n\n\t// Results from the input buffers (in serial_hub.v) of each slave\n\twire [SLAVES*32-1:0]\tslave_nonces;\n\twire [SLAVES*32-1:0]\tslave_debug_sr;\n\twire [SLAVES-1:0]\t\tnew_nonces;\n\n\t// Using the same transmission code as individual miners from serial.v\n\twire\t\tserial_send;\n\twire\t\tserial_busy;\n\twire [31:0]\tgolden_nonce;\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) sertx (.clk(uart_clk), .TxD(TxD), .send(serial_send), .busy(serial_busy), .word(golden_nonce));\n\n\thub_core #(.SLAVES(SLAVES)) hc (.uart_clk(uart_clk), .new_nonces(new_nonces), .golden_nonce(golden_nonce), .serial_send(serial_send), .serial_busy(serial_busy), .slave_nonces(slave_nonces));\n\n\t// Common workdata input for local miners\n\twire [255:0]\tdata1, data2;\n\twire [127:0]\tdata3;\n\twire [31:0]\t\ttarget;\n\treg  [31:0]\t\ttargetreg = 32'h000007ff;\t// Start at sane value (overwritten by serial_receive)\n\twire\t\t\trx_done;\t\t// Signals hashcore to reset the nonce\n\t\t\t\t\t\t\t\t\t// NB in my implementation, it loads the nonce from data3 which should be fine as\n\t\t\t\t\t\t\t\t\t// this should be zero, but also supports testing using non-zero nonces.\n\n\t// Synchronise across clock domains from uart_clk to hash_clk\n\t// This probably looks amateurish (mea maxima culpa, novice verilogger at work), but should be OK\n\treg rx_done_toggle = 1'b0;\t\t// uart_clk domain\n\talways @ (posedge uart_clk)\n\t\trx_done_toggle <= rx_done_toggle ^ rx_done;\n\n\treg rx_done_toggle_d1 = 1'b0;\t// hash_clk domain\n\treg rx_done_toggle_d2 = 1'b0;\n\treg rx_done_toggle_d3 = 1'b0;\n\t\n\twire loadnonce;\n\tassign loadnonce = rx_done_toggle_d3 ^ rx_done_toggle_d2;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\trx_done_toggle_d1 <= rx_done_toggle;\n\t\trx_done_toggle_d2 <= rx_done_toggle_d1;\n\t\trx_done_toggle_d3 <= rx_done_toggle_d2;\n\t\tif (loadnonce)\n\t\t\ttargetreg <= target;\n\tend\n\t// End of clock domain sync\n\n\twire [31:0] mod_target;\n\n`ifdef USE_DYN_PLL\n\t// Top byte of target is clock multiplier, 2nd byte is validation (one's complement of clock multiplier)\n\t// These bytes are always zero in normal getwork, so we now hard code in mod_target and use them to set clock speed.\n\t// NB The pll controller is in uart_clk domain so use serial_receive signals directly\n\t// wire [7:0]invtarg;\t\t\t\t\t// Just checking the syntax in simulator, DELETE\n\t// assign invtarg = ~target[24:16];\n\talways @ (posedge uart_clk)\n\tbegin\n\t\tdyn_pll_start <= 0;\n\t\t// A sanity check to reduce the risk of speed being set to garbage\n\t\t// Top byte of target is speed, second byte MUST be its inverse, and neither must be zero (which also rules out all ones)\n\t\tif (rx_done && target[31:24] != dyn_pll_speed && target[31:24] != 0 && target[23:16] != 0 && target[31:24] == ~target[23:16])\n\t\t// if (rx_done && target[31:24] != dyn_pll_speed && target[31:24] != 0)\t// Simpler version for DEBUG, does no verification\n\t\tbegin\n\t\t\tdyn_pll_speed <= target[31:24];\n\t\t\tdyn_pll_start <= 1;\n\t\tend\n\tend\n\tassign mod_target = { 16'd0, targetreg[15:0] };\t// Ignore top two bytes\n`else\n\t// Its better to always hard-wire the 16 MSB to zero ... if comms noise sets these bits it completely de-syncs,\n\t// generating a continuous stream of golden_nonces overwhelming the python driver which can't then reset the target.\n\t// assign mod_target = targetreg;\t\t\t\t// Original 32 bit target\n\tassign mod_target = { 16'd0, targetreg[15:0] };\t// Ignore top two bytes\n`endif\n\t\n\tserial_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) serrx (.clk(uart_clk), .RxD(RxD), .data1(data1),\n\t\t\t\t\t\t.data2(data2), .data3(data3), .target(target), .rx_done(rx_done));\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\n\t// Local miners now directly connected\n\tgenerate\n\t\tgenvar i;\n\t\tfor (i = 0; i < LOCAL_MINERS; i = i + 1)\n\t\t// begin: for_local_miners ... too verbose, so...\n\t\tbegin: miners\n\t\t\twire [31:0] nonce_out;\t// Not used\n\t\t\twire [2:0] nonce_core = i;\n\t\t\twire gn_match;\n\t\t\twire salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift;\n\t\t\twire [SBITS-1:0] salsa_din;\n\t\t\twire [SBITS-1:0] salsa_dout;\n\t\t\twire [3:0] dummy;\t// So we can ignore top 4 bits of slave_debug_sr\n\n\t\t\t// Currently one pbkdfengine per salsaengine - TODO share the pbkdfengine for several salsaengines\n\t\t\tpbkdfengine #(.SBITS(SBITS)) P\n\t\t\t\t(.hash_clk(hash_clk), .pbkdf_clk(pbkdf_clk), .data1(data1), .data2(data2), .data3(data3), .target(mod_target),\n\t\t\t\t.nonce_msb({nonce_chip, nonce_core}), .nonce_out(nonce_out), .golden_nonce_out(slave_nonces[i*32+31:i*32]),\n\t\t\t\t.golden_nonce_match(gn_match), .loadnonce(loadnonce),\n\t\t\t\t.salsa_din(salsa_din), .salsa_dout(salsa_dout), .salsa_busy(salsa_busy), .salsa_result(salsa_result),\n\t\t\t\t.salsa_reset(salsa_reset), .salsa_start(salsa_start), .salsa_shift(salsa_shift));\n\n\t\t\tsalsaengine #(.ADDRBITS(ADDRBITS), .SBITS(SBITS)) S\n\t\t\t\t(.hash_clk(hash_clk), .reset(salsa_reset), .din(salsa_din), .dout(salsa_dout),\n\t\t\t\t.shift(salsa_shift), .start(salsa_start), .busy(salsa_busy), .result(salsa_result) );\n\t\t\t\t\t\n\t\t\t// Synchronise across clock domains from pbkdf_clk to uart_clk for: assign new_nonces[i] = gn_match;\n\t\t\treg gn_match_toggle = 1'b0;\t\t// hash_clk domain\n\t\t\talways @ (posedge pbkdf_clk)\n\t\t\t\tgn_match_toggle <= gn_match_toggle ^ gn_match;\n\n\t\t\treg gn_match_toggle_d1 = 1'b0;\t// uart_clk domain\n\t\t\treg gn_match_toggle_d2 = 1'b0;\n\t\t\treg gn_match_toggle_d3 = 1'b0;\n\n\t\t\tassign new_nonces[i] = gn_match_toggle_d3 ^ gn_match_toggle_d2;\n\n\t\t\talways @ (posedge uart_clk)\n\t\t\tbegin\n\t\t\t\tgn_match_toggle_d1 <= gn_match_toggle;\n\t\t\t\tgn_match_toggle_d2 <= gn_match_toggle_d1;\n\t\t\t\tgn_match_toggle_d3 <= gn_match_toggle_d2;\n\t\t\tend\n\t\t\t// End of clock domain sync\n\t\tend // for\n\tendgenerate\n\n\t// External miner ports, results appended to the same\n\t// slave_nonces/new_nonces as local ones\n\toutput [EXT_PORTS-1:0] extminer_txd;\n\tinput [EXT_PORTS-1:0]  extminer_rxd;\n\t// wire [EXT_PORTS-1:0]  extminer_rxd_debug = 1'b1;\t// DISABLE INPUT\n\tassign extminer_txd = {EXT_PORTS{RxD}};\n\n\tgenerate\n\t\tgenvar j;\n\t\tfor (j = LOCAL_MINERS; j < SLAVES; j = j + 1)\n\t\t// begin: for_ports ... too verbose, so ...\n\t\tbegin: ports\n\t\t\tslave_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) slrx (.clk(uart_clk), .RxD(extminer_rxd[j-LOCAL_MINERS]), .nonce(slave_nonces[j*32+31:j*32]), .new_nonce(new_nonces[j]));\n\t\tend\n\tendgenerate\n\n\toutput [3:0] led;\n\tassign led[1] = ~RxD;\n\t// assign led[2] = ~TxD;\n\t// assign led[3] = ~ (TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED - held low (the TMP pins are PULLUP, this is a fudge to\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// avoid warning about unused inputs)\n\t\n\tassign led[3] = ~first_dcm_locked | ~dcm_locked | dcm_status[2] | ~(TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED now dcm status\n\n`define FLASHCLOCK\t\t// Gives some feedback as the the actual clock speed\n\n`ifdef FLASHCLOCK\n\treg [26:0] hash_count = 0;\n\treg [3:0] sync_hash_count = 0;\n\talways @ (posedge uart_clk)\n\t\tif (rx_done)\n\t\t\tsync_hash_count[0] <= ~sync_hash_count[0];\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tsync_hash_count[3:1] <= sync_hash_count[2:0];\n\t\thash_count <= hash_count + 1'b1;\n\t\tif (sync_hash_count[3] != sync_hash_count[2])\n\t\t\thash_count <= 0;\n\tend\n\tassign led[2] = hash_count[26];\n`else\n\tassign led[2] = ~TxD;\n`endif\n\n\t// Light up only from locally found nonces, not ext_port results\n\tpwm_fade pf (.clk(uart_clk), .trigger(|new_nonces[LOCAL_MINERS-1:0]), .drive(led[0]));\n   \nendmodule\n"
  },
  {
    "path": "experimental/LX150-SLOWEIGHT-A/pbkdfengine.v",
    "content": "/* pbkdfengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`define ICARUS\t\t\t// Comment this out when using the altera virtual_wire interface in ltcminer.v\n\t\n`timescale 1ns/1ps\n\nmodule pbkdfengine\n\t(hash_clk, pbkdf_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce,\n\t\t\tsalsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift);\n\n\tinput hash_clk;\t\t\t// Just drives shift register\n\tinput pbkdf_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\n\toutput [31:0] nonce_out;\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] salsa_dout;\n\toutput [SBITS-1:0] salsa_din;\n\n\tinput salsa_busy, salsa_result;\t// NB hash_clk domain\n\toutput salsa_reset;\n\toutput salsa_start;\n\toutput reg salsa_shift = 1'b0;\t// NB hash_clk domain\n\n\treg [4:0]resetcycles = 5'd0;\n\treg reset = 1'b0;\n\tassign salsa_reset = reset;\t\t// Propagate reset to salsaengine\n\n`ifdef WANTCYCLICRESET\t\t\n\treg [23:0]cycresetcount = 24'd0;\n`endif\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\t// Hard code a 24 cycle reset (NB assumes THREADS=16 in salsaengine, else we need more)\n\t\t// NB hash_clk is faster than pbkdf_clk so the salsaengine will actually be initialised well before\n\t\t// this period ends, but keep to 24 for now as simulation uses equal pbkdf and salsa clock speeds.\n\t\tresetcycles <= resetcycles + 1'd1;\n\t\tif (resetcycles == 5'd0)\n\t\t\treset <= 1'b1;\n\t\tif (resetcycles == 5'd24)\n\t\tbegin\n\t\t\treset <= 1'b0;\n\t\t\tresetcycles <= 5'd24;\n\t\tend\n`ifdef WANTCYCLICRESET\t\t\n\t\t// Cyclical reset every 2_500_000 clocks to ensure salsa pipeline does not drift out of sync\n\t\t// This may be unneccessary if we reset every loadnonce\n\t\t// Actually it seems to do more harm than good, so disabled\n\t\tcycresetcount <= cycresetcount + 1'd1;\n\t\tif (cycresetcount == 2_500_000)\t// 10 per second at 25MHz (adjust as neccessary)\n\t\tbegin\n\t\t\tcycresetcount <= 24'd0;\n\t\t\tresetcycles <= 5'd0;\n\t\tend\n`endif\t\t\n\t\t// Reset on loadnonce (the hash results will be junk anyway since data changes, so no loss of shares)\n\t\tif (loadnonce)\n\t\t\tresetcycles <= 5'd0;\n\tend\n\t\n\t`ifndef ICARUS\n\treg [31:0] nonce_previous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\t`endif\n\n\t`ifndef NOMULTICORE\n\t`ifdef SIM\n\t\treg [27:0] nonce_cnt = 28'h318f;\t// Start point for simulation (NB also define SIM in serial.v)\n\t`else\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t`endif\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\tassign nonce_out = nonce;\n\n\treg [31:0] nonce_sr = 32'd0;\t\t// Nonce is shifted to salsaengine for storage/retrieval (hash_clk domain)\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\treg [2:0] nonce_wait = 3'd0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [2:0] blockcnt = 3'd0;\t\t// Takes values 1..5 for block iteration\n\treg [1023:0] Xbuf = 1024'd0;\t// Shared input/output buffer and shift register (hash_clk domain)\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\tassign salsa_din = Xbuf[1023:1024-SBITS];\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\t\n\t// MixOut is little-endian word format to match scrypt.c so convert back to big-endian\n\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] mix;\n\t\tassign mix = Xbuf[`IDX(i)];\t\t// NB MixOut now shares Xbuf since shifted in/out\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\n\t// Interface control. This should be OK provided the threads remain evenly spaced (hence we reset on loadnonce)\n\t\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\treg Clr_SMixOutRdy = 1'b0;\n\twire Clr_SMixInRdy;\n\twire Set_SMixOutRdy;\n\n\treg [4:0]salsa_busy_d = 0;\t\t\t// Sync to pbkdf_clk domain\n\treg [4:0]salsa_result_d = 0;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\t// Sync to pbkdf_clk domain\n\t\tsalsa_busy_d[0] <= salsa_busy;\n\t\tif (salsa_busy & ~ salsa_busy_d[0])\n\t\t\tsalsa_busy_d[1] <= ~ salsa_busy_d[1];\t\t// Toggle on busy going high\n\t\t\n\t\tsalsa_result_d[0] <= salsa_result;\n\t\tif (salsa_result & ~ salsa_result_d[0])\n\t\t\tsalsa_result_d[1] <= ~ salsa_result_d[1];\t// Toggle on result going high\n\tend\n\t\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tsalsa_busy_d[4:2] <= salsa_busy_d[3:1];\n\t\tsalsa_result_d[4:2] <= salsa_result_d[3:1];\n\t\t\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\t\t\t\n\t\t// CARE there is a race with Set_SMixInRdy, Clr_SMixOutRdy which are set in the FSM\n\t\t// Need to assert reset for several cycles to ensure consistency (acutally use 15 since salsaengine needs more)\n\t\tif (reset)\n\t\tbegin\t\t\t\t\t\t\t// Reset takes priority\n\t\t\tSMixInRdy_state <= 1'b0;\n\t\t\tSMixOutRdy_state <= 1'b0;\n\t\tend\n\tend\n\t\n\tassign Clr_SMixInRdy = SMixInRdy_state & (salsa_busy_d[3] ^ salsa_busy_d[4]);\t\t\t// Clear on transition to busy\n\t\n\tassign Set_SMixOutRdy = ~SMixOutRdy_state & (salsa_result_d[3] ^ salsa_result_d[4]);\t// Set on transition to result\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\tassign salsa_start = SMixInRdy;\n\t\t\n\t// Clock crossing flags for shift register control (span pbkdf_clk, hash_clk domains)\n\treg [3:0]Xbuf_load_request = 1'b0;\n\treg [3:0]shift_request =  1'b0;\n\treg [3:0]shift_acknowledge = 1'b0;\n\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz)\n\t\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_NONCE=22, S_SHIFT_IN=41, S_SHIFT_OUT=42,\t\t\t\t// Direction relative to salsa unit\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\treg start_output = 0;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\n\t\tshift_acknowledge[3:1] <= shift_acknowledge[2:0];\t// Clock crossing\n\n\t\t`ifdef ICARUS\n\t\tif (loadnonce)\t\t\t\t// Separate clock domains means comparison is unsafe\n\t\t`else\n\t\tif (loadnonce || (nonce_previous_load != data3[127:96]))\n\t\t`endif\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_previous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\t`ifndef ICARUS\n\t\t\tnonce_previous_load <= data3[127:96];\n\t\t\t`endif\n\t\tend\n\t\t\n\t\tif (reset == 1'b1)\n\t\tbegin\n\t\t\tstate <= S_IDLE;\n\t\t\tstart_output <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tif (SMixOutRdy & ~start_output)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\t// Request shifter to start\n\t\t\t\t\t\tstate <= S_SHIFT_OUT;\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (start_output ||\t// Process output\n\t\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'b0;\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\t\tblockcnt <= 3'd1;\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_sr : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\t\t\n\t\t\t\tS_B6: begin\n\t\t\t\t\t\tkhash <= tx_hash;\t\t// Save temporarily (for Xbuf)\n\n\t\t\t\t\t\tXbuf_load_request[0] <= ~Xbuf_load_request[0];\t// NB also loads nonce_sr\n\n\t\t\t\t\t\tif (blockcnt == 3'd5)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tnonce_wait <= 3'd7;\n\t\t\t\t\t\t\tstate <= S_NONCE;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_NONCE: begin\n\t\t\t\t\t\t// Need to delay a few clocks for Xbuf_load_request to complete\n\t\t\t\t\t\tnonce_wait <= nonce_wait - 1'd1;\n\t\t\t\t\t\tif (nonce_wait == 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 1'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 1'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\n\t\t\t\t\t\t\tstate <= S_SHIFT_IN;\n\t\t\t\t\t\tend\n\t\t\t\t\n\t\t\t\tend\n\t\t\t\tS_SHIFT_IN: begin\t\t\t\t\t\t\t// Shifting from PBKDF2_SHA256 to salsa\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tSet_SMixInRdy <= 1'd1;\t\t\t\t// Flag salsa to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_SHIFT_OUT: begin\t\t\t\t\t\t\t// Shifting from salsa to PBKDF2_SHA256\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'd1;\t\t\t\t// Flag self to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_sr;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (state==S_R18)\n\t\t$display (\"final_hash %x\\n\", tx_hash);\n`endif\n\tend\n\n\t// Shift register control - NB hash_clk domain\n\t\n\treg\t[10:0]shift_count = 11'd0;\t// hash_clk domain\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tif (reset)\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b0;\n\t\t\tshift_count <= 11'd0;\n\t\tend\n\n\t\t// Clock crossing logic\n\t\tXbuf_load_request[3:1] <= Xbuf_load_request[2:0];\n\t\tif (Xbuf_load_request[3] != Xbuf_load_request[2])\n\t\tbegin\n\t\t\t// Shift output into X buffer from MSB->LSB\n\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\tXbuf[1023:768] <= khash;\n\n\t\t\tnonce_sr <= nonce;\t// Loaded several times, but of no consequence\n\t\tend\n\t\t\n\t\tshift_request[3:1] <= shift_request[2:0];\n\t\tif (shift_request[3] != shift_request[2])\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b1;\n\t\tend\n\n\t\tif (salsa_shift)\n\t\tbegin\n\t\t\tshift_count <= shift_count + 1'b1;\n\t\t\tXbuf <= { Xbuf[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], salsa_dout };\n\t\tend\n\t\t\n\t\tif (shift_count == (1024+32)/SBITS-1)\n\t\tbegin\n\t\t\tshift_acknowledge[0] = ~shift_acknowledge[0];\n\t\t\tshift_count <= 0;\n\t\t\tsalsa_shift <= 0;\n\t\tend\n\tend\n\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(pbkdf_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\nendmodule"
  },
  {
    "path": "experimental/LX150-SLOWEIGHT-A/salsa_sloweight.v",
    "content": "/* salsa_sloweight.v\n*\n* Copyright (c) 2013 kramble\n* Derived from scrypt.c Copyright 2009 Colin Percival, 2011 ArtForz\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\nmodule salsa (clk, B, Bx, Bo, X0out, Xaddr);\n\n// Latency 8 clock cycles, approx 40nS propagation delay (SLOW!)\n\ninput clk;\n// input feedback;\ninput [511:0]B;\ninput [511:0]Bx;\n// output reg [511:0]Bo;\t// Output is registered\noutput [511:0]Bo;\t\t\t// Output is async\noutput [511:0]X0out;\t\t// Becomes new X0\noutput [9:0] Xaddr;\nwire [9:0] xa1, xa2, xa3, xa4, ya1, ya2, ya3, ya4;\n\nreg [511:0]x1d1;\nreg [511:0]x1d2;\nreg [511:0]x1d3;\nreg [511:0]x1d4;\n\nreg [511:0]Xod1;\nreg [511:0]Xod2;\nreg [511:0]Xod3;\nreg [511:0]X0out;\n\nreg [511:0]xxd1;\nreg [511:0]xxd2;\nreg [511:0]xxd3;\nreg [511:0]xxd4;\n\nreg [511:0]yyd1;\nreg [511:0]yyd2;\nreg [511:0]yyd3;\nreg [511:0]yyd4;\n\nwire [511:0]xx;\t\t\t// Initial xor\nwire [511:0]x1;\t\t\t// Salasa core outputs\nwire [511:0]x2;\nwire [511:0]x3;\nwire [511:0]xr;\nwire [511:0]Xo;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsax1 (clk, xx, x1, xa1);\nsalsa_core salsax2 (clk, x1, x2, xa2);\nsalsa_core salsax3 (clk, x2, x3, xa3);\nsalsa_core salsax4 (clk, x3, xr, xa4);\n\nwire [511:0]yy;\t\t\t// Initial xor\nwire [511:0]y1;\t\t\t// Salasa core outputs\nwire [511:0]y2;\nwire [511:0]y3;\nwire [511:0]yr;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsay1 (clk, yy, y1, ya1);\nsalsa_core salsay2 (clk, y1, y2, ya2);\nsalsa_core salsay3 (clk, y2, y3, ya3);\nsalsa_core salsay4 (clk, y3, yr, ya4);\n\nassign Xaddr = yyd3[9:0] + ya4;\n\ngenvar i;\ngenerate\n\tfor (i = 0; i < 16; i = i + 1) begin : XX\n\t\t// Initial XOR. NB this adds to the propagation delay of the first salsa, may want register it.\n\t\tassign xx[`IDX(i)] = B[`IDX(i)] ^ Bx[`IDX(i)];\n\t\tassign Xo[`IDX(i)] = xxd4[`IDX(i)] + xr[`IDX(i)];\n\t\tassign yy[`IDX(i)] = x1d4[`IDX(i)] ^ Xo[`IDX(i)];\n\t\tassign Bo[`IDX(i)] = yyd4[`IDX(i)] + yr[`IDX(i)];\t// Async output\n\tend\nendgenerate\n\nalways @ (posedge clk)\nbegin\n\tx1d1 <= Bx;\n\tx1d2 <= x1d1;\n\tx1d3 <= x1d2;\n\tx1d4 <= x1d3;\n\tXod1 <= Xo;\n\tXod2 <= Xod1;\n\tXod3 <= Xod2;\n\tX0out <= Xod3;\t// We output this to become new X0\n\n\txxd1 <= xx;\n\txxd2 <= xxd1;\n\txxd3 <= xxd2;\n\txxd4 <= xxd3;\n\n\tyyd1 <= yy;\n\tyyd2 <= yyd1;\n\tyyd3 <= yyd2;\n\tyyd4 <= yyd3;\nend\n\nendmodule\n\nmodule salsa_core (clk, xx, out, Xaddr);\n\ninput clk;\ninput [511:0]xx;\noutput reg [511:0]out;\t\t// Output is registered\n// output [511:0]out;\t\t// Output is unregistered\noutput [9:0] Xaddr;\n\n// This is clunky due to my lack of verilog skills but it works so elegance can come later\n\nwire [31:0]c00;\t\t\t// Column results\nwire [31:0]c01;\nwire [31:0]c02;\nwire [31:0]c03;\nwire [31:0]c04;\nwire [31:0]c05;\nwire [31:0]c06;\nwire [31:0]c07;\nwire [31:0]c08;\nwire [31:0]c09;\nwire [31:0]c10;\nwire [31:0]c11;\nwire [31:0]c12;\nwire [31:0]c13;\nwire [31:0]c14;\nwire [31:0]c15;\n\nwire [31:0]r00;\t\t\t// Row results\nwire [31:0]r01;\nwire [31:0]r02;\nwire [31:0]r03;\nwire [31:0]r04;\nwire [31:0]r05;\nwire [31:0]r06;\nwire [31:0]r07;\nwire [31:0]r08;\nwire [31:0]r09;\nwire [31:0]r10;\nwire [31:0]r11;\nwire [31:0]r12;\nwire [31:0]r13;\nwire [31:0]r14;\nwire [31:0]r15;\n\nwire [31:0]c00s;\t\t\t// Column sums\nwire [31:0]c01s;\nwire [31:0]c02s;\nwire [31:0]c03s;\nwire [31:0]c04s;\nwire [31:0]c05s;\nwire [31:0]c06s;\nwire [31:0]c07s;\nwire [31:0]c08s;\nwire [31:0]c09s;\nwire [31:0]c10s;\nwire [31:0]c11s;\nwire [31:0]c12s;\nwire [31:0]c13s;\nwire [31:0]c14s;\nwire [31:0]c15s;\n\nwire [31:0]r00s;\t\t\t// Row sums\nwire [31:0]r01s;\nwire [31:0]r02s;\nwire [31:0]r03s;\nwire [31:0]r04s;\nwire [31:0]r05s;\nwire [31:0]r06s;\nwire [31:0]r07s;\nwire [31:0]r08s;\nwire [31:0]r09s;\nwire [31:0]r10s;\nwire [31:0]r11s;\nwire [31:0]r12s;\nwire [31:0]r13s;\nwire [31:0]r14s;\nwire [31:0]r15s;\n\n/* From scrypt.c\n\n#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))\n\tfor (i = 0; i < 8; i += 2) {\n\t\t// Operate on columns\n\t\tx04 ^= R(x00+x12, 7);\tx09 ^= R(x05+x01, 7);\tx14 ^= R(x10+x06, 7);\tx03 ^= R(x15+x11, 7);\n\t\tx08 ^= R(x04+x00, 9);\tx13 ^= R(x09+x05, 9);\tx02 ^= R(x14+x10, 9);\tx07 ^= R(x03+x15, 9);\n\t\tx12 ^= R(x08+x04,13);\tx01 ^= R(x13+x09,13);\tx06 ^= R(x02+x14,13);\tx11 ^= R(x07+x03,13);\n\t\tx00 ^= R(x12+x08,18);\tx05 ^= R(x01+x13,18);\tx10 ^= R(x06+x02,18);\tx15 ^= R(x11+x07,18);\n\n\t\t// Operate on rows\n\t\tx01 ^= R(x00+x03, 7);\tx06 ^= R(x05+x04, 7);\tx11 ^= R(x10+x09, 7);\tx12 ^= R(x15+x14, 7);\n\t\tx02 ^= R(x01+x00, 9);\tx07 ^= R(x06+x05, 9);\tx08 ^= R(x11+x10, 9);\tx13 ^= R(x12+x15, 9);\n\t\tx03 ^= R(x02+x01,13);\tx04 ^= R(x07+x06,13);\tx09 ^= R(x08+x11,13);\tx14 ^= R(x13+x12,13);\n\t\tx00 ^= R(x03+x02,18);\tx05 ^= R(x04+x07,18);\tx10 ^= R(x09+x08,18);\tx15 ^= R(x14+x13,18);\n\t}\n*/\n\n// cols\n\nassign c04s = xx[`IDX(0)] + xx[`IDX(12)];\nassign c04 = xx[`IDX(4)] ^ { c04s[24:0], c04s[31:25] };\nassign c09s = xx[`IDX(5)] + xx[`IDX(1)];\nassign c09 = xx[`IDX(9)] ^ { c09s[24:0], c09s[31:25] };\nassign c14s = xx[`IDX(10)] + xx[`IDX(6)];\nassign c14 = xx[`IDX(14)] ^ { c14s[24:0], c14s[31:25] };\nassign c03s = xx[`IDX(15)] + xx[`IDX(11)];\nassign c03 = xx[`IDX(03)] ^ { c03s[24:0], c03s[31:25] };\n\nassign c08s = c04 + xx[`IDX(0)];\nassign c08 = xx[`IDX(8)] ^ { c08s[22:0], c08s[31:23] };\nassign c13s = c09 + xx[`IDX(5)];\nassign c13 = xx[`IDX(13)] ^ { c13s[22:0], c13s[31:23] };\nassign c02s = c14 + xx[`IDX(10)];\nassign c02 = xx[`IDX(2)] ^ { c02s[22:0], c02s[31:23] };\nassign c07s = c03 + xx[`IDX(15)];\nassign c07 = xx[`IDX(7)] ^ { c07s[22:0], c07s[31:23] };\n\nassign c12s = c08 + c04;\nassign c12 = xx[`IDX(12)] ^ { c12s[18:0], c12s[31:19] };\nassign c01s = c13 + c09;\nassign c01 = xx[`IDX(1)] ^ { c01s[18:0], c01s[31:19] };\nassign c06s = c02 + c14;\nassign c06 = xx[`IDX(6)] ^ { c06s[18:0], c06s[31:19] };\nassign c11s = c07 + c03;\nassign c11 = xx[`IDX(11)] ^ { c11s[18:0], c11s[31:19] };\n\nassign c00s = c12 + c08;\nassign c00 = xx[`IDX(0)] ^ { c00s[13:0], c00s[31:14] };\nassign c05s = c01 + c13;\nassign c05 = xx[`IDX(5)] ^ { c05s[13:0], c05s[31:14] };\nassign c10s = c06 + c02;\nassign c10 = xx[`IDX(10)] ^ { c10s[13:0], c10s[31:14] };\nassign c15s = c11 + c07;\nassign c15 = xx[`IDX(15)] ^ { c15s[13:0], c15s[31:14] };\n\n// rows\n\nassign r01s = c00 + c03;\nassign r01 = c01 ^ { r01s[24:0], r01s[31:25] };\nassign r06s = c05 + c04;\nassign r06 = c06 ^ { r06s[24:0], r06s[31:25] };\nassign r11s = c10 + c09;\nassign r11 = c11 ^ { r11s[24:0], r11s[31:25] };\nassign r12s = c15 + c14;\nassign r12 = c12 ^ { r12s[24:0], r12s[31:25] };\n\nassign r02s = r01 + c00;\nassign r02 = c02 ^ { r02s[22:0], r02s[31:23] };\nassign r07s = r06 + c05;\nassign r07 = c07 ^ { r07s[22:0], r07s[31:23] };\nassign r08s = r11 + c10;\nassign r08 = c08 ^ { r08s[22:0], r08s[31:23] };\nassign r13s = r12 + c15;\nassign r13 = c13 ^ { r13s[22:0], r13s[31:23] };\n\nassign r03s = r02 + r01;\nassign r03 = c03 ^ { r03s[18:0], r03s[31:19] };\nassign r04s = r07 + r06;\nassign r04 = c04 ^ { r04s[18:0], r04s[31:19] };\nassign r09s = r08 + r11;\nassign r09 = c09 ^ { r09s[18:0], r09s[31:19] };\nassign r14s = r13 + r12;\nassign r14 = c14 ^ { r14s[18:0], r14s[31:19] };\n\nassign r00s = r03 + r02;\nassign r00 = c00 ^ { r00s[13:0], r00s[31:14] };\nassign r05s = r04 + r07;\nassign r05 = c05 ^ { r05s[13:0], r05s[31:14] };\nassign r10s = r09 + r08;\nassign r10 = c10 ^ { r10s[13:0], r10s[31:14] };\nassign r15s = r14 + r13;\nassign r15 = c15 ^ { r15s[13:0], r15s[31:14] };\n\n\n// assign out = { r15, r14, r13, r12, r11, r10, r09, r08, r07, r06, r05, r04, r03, r02, r01, r00 };\n\n// Registered output ...\nwire [511:0]xo;\t\t\t// Rename row results\nassign xo = { r15, r14, r13, r12, r11, r10, r09, r08, r07, r06, r05, r04, r03, r02, r01, r00 };\nassign Xaddr = xo[9:0];\n\n// Output is registered, but may want to make it async\nalways @ (posedge clk)\n\tout <= xo;\n\nendmodule\n"
  },
  {
    "path": "experimental/LX150-SLOWEIGHT-A/salsaengine.v",
    "content": "/* salsaengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n// NB HALFRAM no longer applies, configure via parameters ADDRBITS, THREADS\n\n// Bracket this config option in SIM so we don't accidentally leave it set in a live build\n`ifdef SIM\n//`define ONETHREAD\t// Start one thread only (for SIMULATION less confusing and faster startup)\n`endif\n\n`timescale 1ns/1ps\n\nmodule salsaengine (hash_clk, reset, din, dout, shift, start, busy, result );\n\n\n\tinput hash_clk;\n\tinput reset;\t// NB pbkdf_clk domain (need a long reset (at least THREADS+4) to initialize correctly, this is done in pbkdfengine\n\tinput shift;\n\tinput start;\t// NB pbkdf_clk domain\n\toutput busy;\n\toutput reg result = 1'b0;\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] din;\n\toutput [SBITS-1:0] dout;\n\n\t// Configure ADDRBITS to allocate RAM for core (automatically sets LOOKAHEAD_GAP)\n\t// NB do not use ADDRBITS > 13 for THREADS=8 or ADDRBITS > 14 for THREADS=16 as this is more than\n\t// a full scratchpad and the calculation for INT_BITS will be invalid.\n\n\t// These settings are now overriden in ltcminer_icarus.v determined by LOCAL_MINERS ...\n\t// These values are for THREADS=8, scratchpad sizes are halved for THREADS=16\n\t// parameter ADDRBITS = 14;\t// 16MBit RAM allocated to core, full scratchpad for THREADS=16(will not fit LX150)\n\t// parameter ADDRBITS = 13;\t//  8MBit RAM allocated to core, full scratchpad (will not fit LX150)\n\tparameter ADDRBITS = 12;\t//  4MBit RAM allocated to core, half scratchpad\n\t// parameter ADDRBITS = 11;\t//  2MBit RAM allocated to core, quarter scratchpad\n\t// parameter ADDRBITS = 10;\t//  1MBit RAM allocated to core, eighth scratchpad\n\n\t// Do not change THREADS - this must match the salsa pipeline (8 or 16 cycle latency for 8 or 16 threads)\n\tparameter THREADS = 8;\t\t// NB Phase has THREADS+1 cycles\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n\tparameter THREADS_BITS = clog2(THREADS);\n\t\n\treg [THREADS_BITS:0]phase = 0;\n\treg [THREADS_BITS:0]phase_d = THREADS;\n\treg reset_d=0, fsmreset=0, start_d=0, fsmstart=0;\n\n\talways @ (posedge hash_clk)\t\t// Phase control and sync\n\tbegin\n\t\tphase <= (phase == THREADS) ? 0 : phase + 1;\n\t\tphase_d <= phase;\n\t\treset_d <= reset;\t\t\t// Synchronise to hash_clk domain\n\t\tfsmreset <= reset_d;\n\t\tstart_d <= start;\n\t\tfsmstart <= start_d;\n\tend\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\tparameter XSmix = 0, XSload = 1, XSram = 2;\t// One-hot since these map directly to mux contrls\n\n\treg [1:0] XCtl = XSmix;\n\n\tparameter R_IDLE=0, R_START=1, R_LOAD=2, R_WRITE=3, R_MIX=4, R_INT=5, R_WAIT=6;\n\treg [2:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs\n\treg addrwriteMix = 1'b0;\n\treg addrreadInit = 1'b0;\n\treg addrreadSave = 1'b0;\n\treg xoren = 1'b0;\n\n\t// NB This caclulation does NOT work for ADDRBITS>13 with THREADS=8 or ADDRBITS>14 with THREADS=16\n\tparameter INT_BITS = THREADS_BITS - ADDRBITS + 10;\t// Max intcycle value is 15 for THREADS=16 and ADDRBITS=10, needing 5 bits\n\t// Where INT_BITS==0 we have a full scratchpad and intcycles is not used (though a 1 bit reg[0:0] is still allocated)\n\tparameter INT_BITX = (INT_BITS > 0) ? INT_BITS : INT_BITS+1;\t// Workaround for compilation errors in unused code branches\n\n\treg [INT_BITS:0] intcycles = 0;\t\t\t\t\t\t// Number of interpolation cycles required\n\n\twire [511:0] Xmix;\n\treg [511:0] X0;\n\treg [511:0] X1;\n\twire [511:0] X0in;\n\twire [511:0] X1in;\n\twire [511:0] X0out;\n\treg [1023:0] salsaShiftReg;\n\treg [31:0] nonce_sr;\t\t\t// In series with salsaShiftReg\n\tassign dout = salsaShiftReg[1023:1024-SBITS];\n\n\t// sstate is implemented in ram (alternatively could use a rotating shift register)\n\treg [INT_BITS+28:0] sstate [THREADS-1:0];\t\t// NB initialized via a long reset (see pbkdfengine)\n\t// List components of sstate here for ease of maintenance ...\n\twire [2:0] mstate_in;\n\twire [10:0] cycle_in;\n\twire [9:0] writeaddr_in;\n\twire doneROM_in;\n\twire addrwriteMix_in;\n\twire addrreadInit_in;\n\twire addrreadSave_in;\n\twire [INT_BITS:0] intcycles_in;\n\n\twire [9:0] writeaddr_next = writeaddr_in + 10'd1;\n\n\treg [31:0] snonce [THREADS-1:0];\t\t\t\t\t// Nonce store. Note bidirectional loading below, this will either implement\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// as registers or dual-port ram, so do NOT integrate with sstate.\n\t\n\t// NB There is no busy_in or result_in as these flags are NOT saved on a per-thread basis\n\n\t// Convert salsaShiftReg to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = salsaShiftReg[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\tend\n\tendgenerate\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of RAM size\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\twire [9:0] Xaddr;\n\twire [ADDRBITS-1:0]rd_addr;\n\twire [ADDRBITS-1:0]wr_addr1;\n\twire [ADDRBITS-1:0]wr_addr2;\n\twire [ADDRBITS-1:0]wr_addr3;\n\twire [ADDRBITS-1:0]wr_addr4;\n\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\t(* S = \"TRUE\" *) reg ram_wren = 1'b0;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\t// Top ram address is reserved for X0Save/X1save, so adjust\n\t\n\twire [15:0] memtop = 16'hfffe;\t// One less than the top memory location (per THREAD bank)\n\t\n\twire [9-INT_BITS:0] adj_addr;\n\n\tif (INT_BITS > 0)\n\t\tassign adj_addr = (Xaddr[9:INT_BITS] == memtop[9:INT_BITS]) ?\n\t\t\t\t\t\t\tmemtop[9-INT_BITS:0] : Xaddr[9:INT_BITS];\n\telse\n\t\tassign adj_addr = Xaddr;\n\t\n\twire [THREADS_BITS-1:0] phase_addr;\t\t\t\t\t// Prefix for read address\n\tassign phase_addr = phase[THREADS_BITS-1:0];\n\treg [THREADS_BITS-1:0] phase_addr_d = 0;\t\t\t// Prefix for write address\n\n\tassign rd_addr = { phase_addr,\n\t\t\t\t\t\t(addrreadSave_in | addrreadInit_in) ?\n\t\t\t\t\t\t\t(addrreadInit_in ? {ADDRBITS-THREADS_BITS{1'b0}} : memtop[ADDRBITS-THREADS_BITS:1])\n\t\t\t\t\t\t:\n\t\t\t\t\t\t\tadj_addr };\n\t\t\n\twire [9:0] writeaddr_adj = addrwriteMix ? memtop[10:1] : writeaddr;\n\t\n\tassign wr_addr1 = { phase_addr_d, writeaddr_adj[9:INT_BITS] };\n\tassign wr_addr2 = { phase_addr_d, writeaddr_adj[9:INT_BITS] };\n\tassign wr_addr3 = { phase_addr_d, writeaddr_adj[9:INT_BITS] };\n\tassign wr_addr4 = { phase_addr_d, writeaddr_adj[9:INT_BITS] };\n\n\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_1 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_2 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_3 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_4 = 0;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr1 = rd_addr | rd_addr_z_1;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr2 = rd_addr | rd_addr_z_2;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr3 = rd_addr | rd_addr_z_3;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr4 = rd_addr | rd_addr_z_4;\n\t\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (rd_addr1, wr_addr1, ram_clk, ram1_din, ram_wren, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (rd_addr2, wr_addr2, ram_clk, ram2_din, ram_wren, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (rd_addr3, wr_addr3, ram_clk, ram3_din, ram_wren, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (rd_addr4, wr_addr4, ram_clk, ram4_din, ram_wren, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\n\t// Two ram data sources, the initial X value and the salsa output\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = XCtl[0] ? X : { Xmix, X0out};\t// Registered input\n\t\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, X0, X1, Xmix, X0out, Xaddr);\n\n\t// Main multiplexer\n\twire [511:0] Zbits;\n\tassign Zbits = {512{xoren}};\t\t// xoren enables xor from ram (else we load from ram)\n\t\n\t// XSMix is now the default and the initial load is now done via RAM to simplify the pipeline\n\tassign X0in =  XCtl[1] ? (X0out & Zbits) ^ ramout[511:0]    : X0out;\n\tassign X1in =  XCtl[1] ? (Xmix  & Zbits) ^ ramout[1023:512] : Xmix;\n\n\t// Salsa FSM - TODO may want to move this into a separate function (for floorplanning), see hashvariant-C\n\n\t// Hold separate state for each thread (a bit of a kludge to avoid rewriting FSM from scratch)\n\t// NB must ensure shift and result do NOT overlap by carefully controlling timing of start signal\n\t// NB Phase has THREADS+1 cycles, but we do not save the state for (phase==THREADS) as it is never active\n\n\tassign { mstate_in, writeaddr_in, cycle_in, doneROM_in, addrwriteMix_in, addrreadInit_in, addrreadSave_in, intcycles_in} =\n\t\t\t\t(phase == THREADS ) ? 0 : sstate[phase];\t\n\t\n\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\n\treg busy_flag = 1'b0;\n\t\n`ifdef ONETHREAD\n\t// TEST CONTROLLER ... just allow a single thread to run (busy is currently a common flag)\n\t// NB the thread automatically restarts after it completes, so its a slight misnomer to say it starts once.\n\treg start_once = 1'b0;\n\twire start_flag;\n\tassign start_flag = fsmstart & ~start_once;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine\n`else\n\t// NB start_flag only has effect when a thread is at R_IDLE, ie after reset, normally a thread will automatically\n\t// restart on completion. We need to spread the R_IDLE starts evenly to ensure proper ooperation. NB the pbkdf\n\t// engine requires busy and result, but this  looks alter itself in the salsa FSM, even though these are global\n\t// flags. Reset periodically (on loadnonce in pbkdfengine) to ensure it stays in sync.\n\treg [15:0] start_count = 0;\n\n\t// For THREADS=8, lookup_gap=2 salsa takes on average 9*(1024+(1024*1.5)) = 23040 clocks, generically 9*1024*(lookup_gap/2+1.5)\n\t// For THREADS=16, use 17*1024*(lookup_gap/2+1.5), where lookupgap is double that for THREADS=8\n\t// This is OK, but only does ADDRBITS=10,11,12 ...\n\t// parameter START_INTERVAL = (THREADS==16) ?\t((ADDRBITS==12) ? 60928 : (ADDRBITS==11) ? 95744 : 165376) / THREADS :\t// 16 threads\n\t//\t\t\t\t\t\t\t\t\t\t\t\t((ADDRBITS==12) ? 23040 : (ADDRBITS==11) ? 36864 :  50688) / THREADS ;\t//  8 threads\n\t// This seems to work OK generically (TODO check full scratchpad) ...\n\tparameter START_INTERVAL = (THREADS+1) * 1024 * ((1 << (15-ADDRBITS)) * THREADS / 32 + 3) / THREADS / 2;\n\n\treg start_flag = 1'b0;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine - this will toggle on transtion through R_START\n`endif\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tX0 <= X0in;\n\t\tX1 <= X1in;\n\t\t\n\t\tif (phase_d != THREADS)\n\t\t\tsstate[phase_d] <= fsmreset ? 0 : { mstate, writeaddr, cycle, doneROM, addrwriteMix, addrreadInit, addrreadSave, intcycles };\n\n\t\tmstate <= mstate_in;\t\t// Set defaults (overridden below as necessary)\n\t\twriteaddr <= writeaddr_in;\n\t\tcycle <= cycle_in;\n\t\tintcycles <= intcycles_in;\n\t\tdoneROM <= doneROM_in;\n\t\taddrwriteMix <= addrwriteMix_in;\n\t\taddrreadInit <= addrreadInit_in;\n\t\taddrreadSave <= addrreadSave_in;\t\t// Overwritten below, but addrreadSave_in is used above\n\t\t\n\t\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\trd_addr_z_1 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_2 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_3 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_4 <= {ADDRBITS{fsmreset}};\n\n\t\tphase_addr_d <= phase[THREADS_BITS-1:0];\n\t\t\n\t\tXCtl <= XSmix;\t\t\t\t// Default states\n\t\taddrreadInit <= 1'b0;\t\t// NB addrreadInit_in is the active control so this DOES need to be in sstate\n\t\taddrreadSave <= 1'b0;\t\t// Ditto\n\t\tram_wren <= 1'b0;\n\t\txoren <= 1'b1;\n\t\t\n\t\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\t\t`ifdef ONETHREAD\n\t\tif (fsmstart && phase!=THREADS)\n\t\t\tstart_once <= 1'b1;\n\t\tif (fsmreset)\n\t\t\tstart_once <= 1'b0;\n\t\t`else\n\t\tstart_count <= start_count + 1;\n\t\t// start_flag <= 1'b0;\t\t\t// Done below when we transition out of R_IDLE\n\t\tif (fsmreset || start_count == START_INTERVAL)\n\t\tbegin\n\t\t\tstart_count <= 0;\n\t\t\tif (~fsmreset && fsmstart)\n\t\t\t\tstart_flag <= 1'b1;\n\t\tend\n\t\t`endif\n\t\t\n\t\t// Could use explicit mux for this ...\n\t\tif (shift)\n\t\tbegin\n\t\t\tsalsaShiftReg <= { salsaShiftReg[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], din};\n\t\tend\n\t\telse\n\t\tif (XCtl[0] && phase_d != THREADS)\t\t// Set at end of previous hash - this is executed regardless of phase\t\t\n\t\tbegin\n\t\t\tsalsaShiftReg <= ramout;\t\t\t// Simultaneously with XSload\n\t\t\tnonce_sr <= snonce[phase_d];\t\t// NB bidirectional load\n\t\t\tsnonce[phase_d] <= nonce_sr;\n\t\tend\n\t\t\n\t\tif (fsmreset == 1'b1)\n\t\tbegin\n\t\t\tmstate <= R_IDLE;\t\t// This will propagate to all sstate slots as we hold reset for 10 cycles\n\t\t\tbusy_flag <= 1'b0;\n\t\t\tresult <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate_in)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\t// R_IDLE only applies after reset. Normally each thread will reenter at S_START and\n\t\t\t\t\t// assumes that input data is waiting (this relies on the threads being started evenly,\n\t\t\t\t\t// hence the interface FSM at the top of this file)\n\t\t\t\t\tif (phase!=THREADS && start_flag)\t// Ensure (phase==THREADS) slot is never active\n\t\t\t\t\tbegin\n\t\t\t\t\t\t`ifndef ONETHREAD\n\t\t\t\t\t\t\tstart_flag <= 1'b0;\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t\t// Toggle the busy flag low to ack pbkdfengine (its usually already set\n\t\t\t\t\t\t\t\t\t\t\t\t// since other threads are running)\n\t\t\t\t\t\tmstate <= R_START;\n\n\t\t\t\t\t\t// We cycle the initial data through the RAM to simplify the data path (costs 17 clocks)\n\t\t\t\t\t\t// Setup to write initial data to ram (on next clock)\n\t\t\t\t\t\twriteaddr <= 0;\n\t\t\t\t\t\taddrwriteMix <= 1'b0;\n\t\t\t\t\t\tram_wren <= 1'b1;\n\n\t\t\t\t\t\t// Setup to read initial data back from ram (17 clocks later)\n\t\t\t\t\t\tXCtl <= XSload;\n\t\t\t\t\t\taddrreadInit <= 1'b1;\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tR_START: begin\t\t\t\t\t// Reentry point after thread completion. ASSUMES new data is ready.\n\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\txoren <= 1'b0;\n\t\t\t\t\tcycle <= 0;\n\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\tbusy_flag <= 1'b1;\n\t\t\t\t\tresult <= 1'b0;\n\t\t\t\t\tmstate <= R_LOAD;\n\t\t\t\tend\n\n\t\t\t\tR_LOAD: begin\t\t\t\t\t// Now loading initial data via RAM to simplify data path (costs 17 clocks)\n\t\t\t\t\twriteaddr <= writeaddr_next;\n\t\t\t\t\tif (INT_BITS == 0)\n\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Full scratchpad needs to write to addr=001 next cycle\n\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\tend\n\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\twriteaddr <= writeaddr_next;\n\n\t\t\t\t\tif (writeaddr_in==1022)\n\t\t\t\t\t\tdoneROM <= 1'b1;\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\t\n\t\t\t\t\tif (doneROM_in)\n\t\t\t\t\tbegin\n\t\t\t\t\t\taddrwriteMix <= 1'b1;\t// Remains set for duration of R_MIX\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Load from ram next cycle (xor'd with XMix)\n\t\t\t\t\t\t// Need this to cover the case of the initial read being interpolated\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_MIX\n\t\t\t\t\t\tif (INT_BITS > 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { 1'b0, Xaddr[INT_BITX-1:0] };\t// Interpolated addresses\n\t\t\t\t\t\t\tif ( Xaddr[9:INT_BITX] ==  memtop[10-INT_BITX:1] )\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { 1'b1, Xaddr[INT_BITX-1:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:INT_BITX] == memtop[10-INT_BITX:1]) || |Xaddr[INT_BITX-1:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 1'b0;\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[INT_BITX-1:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:INT_BITX] ==  memtop[10-INT_BITX:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrreadSave <= 1'b1;\t\t// Preset to read saved data (17 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tram_wren <=\t(INT_BITS > 0) ? ~|writeaddr_next[INT_BITX-1:0] : 1'b1;\t\t\t\t\t\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\tcycle <= cycle_in + 11'd1;\n\t\t\t\t\tif (cycle_in==1023)\n\t\t\t\t\tbegin\n\t\t\t\t\t\t// We now ALWAYS write result to ram, thus simplifying the data path at the cost of 17 clock cycles\n\t\t\t\t\t\tmstate <= R_WAIT;\n\t\t\t\t\t\taddrreadSave <= 1'b1;\t\t// Preset to read saved data (17 clocks later)\n\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Save result\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle (xor'd with XMix)\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_WRITE\n\t\t\t\t\t\tif (INT_BITS > 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { 1'b0, Xaddr[INT_BITX-1:0] };\t\t\t// Interpolated addresses\n\t\t\t\t\t\t\tif ( Xaddr[9:INT_BITX] ==  memtop[10-INT_BITX:1] )\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { 1'b1, Xaddr[INT_BITX-1:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:INT_BITX] == memtop[10-INT_BITX:1]) || |Xaddr[INT_BITX-1:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 1'b0;\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[INT_BITX-1:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:INT_BITX] ==  memtop[10-INT_BITX:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrreadSave <= 1'b1;\t\t// Preset to read saved data (17 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tR_INT: begin\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\tintcycles <= intcycles_in - 1;\n\t\t\t\t\tif (intcycles_in==2)\n\t\t\t\t\t\taddrreadSave <= 1'b1;\t// Preset to read saved data (17 clocks later)\n\t\t\t\t\tif (intcycles_in==1)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Setup to XOR from saved X0/X1 in ram at next cycle\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\tend\n\t\t\t\t\t// Else mstate remains at R_INT so we continue interpolating\n\t\t\t\tend\n\n\t\t\t\tR_WAIT: begin\n\t\t\t\t\t\tif (fsmstart)\t\t\t// Check data input is ready\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\tbusy_flag <= 1'b0;\t\t// Will hold at 0 for 17 clocks until set at R_START\n\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\tmstate <= R_START;\t\t// Restart immediately\n\n\t\t\t\t\t\t\t// We cycle the initial data through the RAM to simplify the data path (costs 17 clocks)\n\t\t\t\t\t\t\t// Setup to write initial data to ram (on next clock)\n\t\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\t\taddrwriteMix <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t// Setup to read initial data back from ram (17 clocks later)\n\t\t\t\t\t\t\tXCtl <= XSload;\n\t\t\t\t\t\t\taddrreadInit <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\taddrreadSave <= 1'b1;\t\t// Preset to read saved data (17 clocks later)\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\t// if (mstate==R_MIX)\n\t//\t$display (\"phase %d cycle %d Xmix %08x\\n\", phase, cycle-1, Xmix[511:480]);\n`endif\n\tend\t// always @(posedge hash_clk)\nendmodule"
  },
  {
    "path": "experimental/LX150-SLOWEIGHT-A/test_icarus.v",
    "content": "// Testbench for ltcminer_icarus.v\n\n`timescale 1ns/1ps\n\n`ifdef SIM\t\t\t\t\t// Avoids wrong top selected if included in ISE/PlanAhead sources\nmodule test_ltcminer ();\n\n\treg clk = 1'b0;\n\treg [31:0] cycle = 32'd0;\n\n\tinitial begin\n\t\tclk = 0;\n\t\t\n\t\twhile(1)\n\t\tbegin\n\t\t\t#5 clk = 1; #5 clk = 0;\n\t\tend\n\tend\n\n\talways @ (posedge clk)\n\tbegin\n\t\tcycle <= cycle + 32'd1;\n\tend\n\t\n\t// Running with default zero's for the data1..3 regs.\n\t// tx_hash=553a4b69b43913a61b42013ce210f713eaa7332e48cda1bdf3b93b10161d0876 at 187,990 nS and\n\t// final_hash (if SIM is defined) at 188,000 nS with golden_nonce_match flag NOT set since it is\n\t// not a diff=32 share. To test golden_nonce, just tweak the target eg 31'hffffffff will match everything\n\t\n\t// With serial input(at comm_clk_frequency=1_000_000), we get rx_done at t=70,220nS, however there is already a\n\t// PBKDF2_SHA256_80_128 loaded in Xbuf (for nonce=00000001). The first final_hash at 188,000 nS is corrupted as\n\t// the input data has changed from all 0's. The Xbuf starts salsa rom at t=188,000 but the nonce is incorrectly\n\t// taken from the newly loaded data so once salsa in complete it also generates a corrupt final_hash at ~362,000 nS.\n\t// Nonce is incremented then the newly loaded data starts PBKDF2_SHA256_80_128, so we must supply a nonce 1 less\n\t// than the expected golden_nonce. The correct PBKDF2_SHA256_80_128 is ready at ~ 197,000 nS. We get final_hash for\n\t// the corrupted work at ~362,000 nS then our required golden_nonce is at 536,180 nS.\n\t// This is only really a problem for simulation. With live hashing we just lose 2 nonces every time getwork is\n\t// loaded, which isn't a big deal.\n\t\t\n\twire RxD;\n\twire TxD;\n\twire extminer_rxd = 0;\n\twire extminer_txd;\n\twire [3:0] dip = 0;\n\twire [3:0] led;\n\twire TMP_SCL=1, TMP_SDA=1, TMP_ALERT=1;\n\t\n\tparameter comm_clk_frequency = 1_000_000;\t// Speeds up serial loading enormously rx_done is at t=70,220nS\n\tparameter baud_rate = 115_200;\n\t\n\tltcminer_icarus #(.comm_clk_frequency(comm_clk_frequency)) uut\n\t\t(clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\t// Send serial data - 84 bytes, matches on nonce 318f (included in data)\n\t// NB starting nonce is 381e NOT 381f (see note above)\n\t\n\t// NORMAL...\n\t// reg [671:0] data = 672'h000007ff0000318e7e71441b141fe951b2b0c7dfc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af75575618e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\n\t// DYNPLL...\n\treg [671:0] data = 672'h55aa07ff0000318e7e71441b141fe951b2b0c7dfc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af75575618e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\t\n\treg\t\t\tserial_send = 0;\n\twire\t\tserial_busy;\n\treg [31:0]\tdata_32 = 0;\n\treg [31:0]\tstart_cycle = 0;\n\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(baud_rate)) sertx (.clk(clk), .TxD(RxD), .send(serial_send), .busy(serial_busy), .word(data_32));\n\n\t// TUNE this according to comm_clk_frequency so we send a single getwork (else it gets overwritten with 0's)\n\t// parameter stop_cycle = 7020;\t\t// For comm_clk_frequency=1_000_000\n\tparameter stop_cycle = 0;\t\t\t// Use this to DISABLE sending data\n\talways @ (posedge clk)\n\tbegin\n\t\tserial_send <= 0;\t\t\t\t// Default\n\t\t// Send data every time tx goes idle (NB the !serial_send is to prevent serial_send\n\t\t// going high for two cycles since serial_busy arrives one cycle after serial_send)\n\t\tif (cycle > 5 && cycle < stop_cycle && !serial_busy && !serial_send)\n\t\tbegin\n\t\t\tserial_send <= 1;\n\t\t\tdata_32 <= data[671:640];\n\t\t\tdata <= { data[639:0], 32'd0 };\n\t\t\tstart_cycle <= cycle;\t\t// Remember each start cycle (makes debugging easier)\n\t\tend\n\tend\n\nendmodule\n`endif"
  },
  {
    "path": "experimental/LX150-SLOWEIGHT-A/xilinx_dpram.v",
    "content": "// xilinx_ram.v - inferring the ram seems to work fine\n\nmodule ram # ( parameter ADDRBITS=10 ) (\n\traddr,\n\twaddr,\n\tclock,\n\tdata,\n\twren,\n\tq);\n\n\tinput\t[ADDRBITS-1:0]  raddr;\n\tinput\t[ADDRBITS-1:0]  waddr;\n\tinput\t  clock;\n\tinput\t[255:0]  data;\n\tinput\t  wren;\n\toutput\t[255:0]  q;\n\n\t//synthesis attribute ram_style of store is block\n\treg [255:0] store [(2 << (ADDRBITS-1))-1:0];\n\treg[ADDRBITS-1:0] raddr_reg;\n\t\n\talways @ (posedge clock)\n\tbegin\n\t\traddr_reg <= raddr;\n\t\tif (wren)\n\t\t\tstore[waddr] <= data;\n\tend\n\t\n\tassign q = store[raddr_reg];\n\t\t\t\nendmodule"
  },
  {
    "path": "experimental/LX150-SLOWEIGHT-A/xilinx_dyn_pll.v",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 1995-2011 Xilinx, Inc.  All rights reserved.\n////////////////////////////////////////////////////////////////////////////////\n//   ____  ____ \n//  /   /\\/   / \n// /___/  \\  /    Vendor: Xilinx \n// \\   \\   \\/     Version : 13.1\n//  \\   \\         Application : xaw2verilog\n//  /   /         Filename : main_pll.v\n// /___/   /\\     Timestamp : 06/03/2011 01:58:13\n// \\   \\  /  \\ \n//  \\___\\/\\___\\ \n//\n//Command: xaw2verilog -st /home/teknohog/dcm2/ipcore_dir/./main_pll.xaw /home/teknohog/dcm2/ipcore_dir/./main_pll\n//Design Name: main_pll\n//Device: xc3s500e-4fg320\n//\n// Module main_pll\n// Generated by Xilinx Architecture Wizard\n// Written for synthesis tool: XST\n\n`timescale 1ns / 1ps\n\nmodule dyn_pll # (parameter SPEED_MHZ = 25 )\n\t(CLKIN_IN, \n\tCLKFX1_OUT, \n\tCLKFX2_OUT, \n\tCLKDV_OUT,\n\tDCM_SP_LOCKED_OUT,\n\tdcm_progclk,\n\tdcm_progdata,\n\tdcm_progen,\n\tdcm_reset,\n\tdcm_progdone,\n\tdcm_locked,\n\tdcm_status);\n\t\n\tinput CLKIN_IN;\n\twire CLKIN_IBUFG_OUT;\n\twire CLK0_OUT;\n\toutput CLKFX1_OUT;\n\toutput CLKFX2_OUT;\n\toutput CLKDV_OUT;\n\toutput DCM_SP_LOCKED_OUT;\n\n\tinput dcm_progclk;\n\tinput dcm_progdata;\n\tinput dcm_progen;\n\tinput dcm_reset;\n\toutput dcm_progdone;\n\toutput dcm_locked;\n\toutput [2:1] dcm_status;\n\t\n\twire CLKFB_IN;\n\twire CLKIN_IBUFG;\n\twire CLK0_BUF;\n\twire CLKFX1_BUF;\n\twire CLKFX2_BUF;\n\twire CLKDV_BUF;\n\twire GND_BIT;\n\twire dcm_progclk_buf;\n\n\tassign GND_BIT = 0;\n\tassign CLKIN_IBUFG_OUT = CLKIN_IBUFG;\n\tassign CLK0_OUT = CLKFB_IN;\n\t\n\tIBUFG  CLKIN_IBUFG_INST (.I(CLKIN_IN), \n\t\t.O(CLKIN_IBUFG));\n\tBUFG  CLK0_BUFG_INST (.I(CLK0_BUF), \n\t\t.O(CLKFB_IN));\n\tBUFG  CLKFX1_BUFG_INST (.I(CLKFX1_BUF), \n\t\t.O(CLKFX1_OUT));\n\tBUFG  CLKFX2_BUFG_INST (.I(CLKFX2_BUF), \n\t\t.O(CLKFX2_OUT));\n\tBUFG  CLKDV_BUFG_INST (.I(CLKDV_BUF), \n\t\t.O(CLKDV_OUT));\n\tBUFG  DCMPROGCLK_BUFG_INST (.I(dcm_progclk), \n\t\t.O(dcm_progclk_buf));\n\n\t// 100 MHZ osc gives fixed 50MHz CLKFX1, 12.5MHZ CLKDV\n\tDCM_SP #( .CLK_FEEDBACK(\"1X\"), .CLKDV_DIVIDE(8.0), .CLKFX_DIVIDE(8),\n\t\t.CLKFX_MULTIPLY(4), .CLKIN_DIVIDE_BY_2(\"FALSE\"), \n\t\t.CLKIN_PERIOD(10.000), .CLKOUT_PHASE_SHIFT(\"NONE\"), \n\t\t.DESKEW_ADJUST(\"SYSTEM_SYNCHRONOUS\"), .DFS_FREQUENCY_MODE(\"LOW\"), \n\t\t.DLL_FREQUENCY_MODE(\"LOW\"), .DUTY_CYCLE_CORRECTION(\"TRUE\"), \n\t\t.FACTORY_JF(16'hC080), .PHASE_SHIFT(0), .STARTUP_WAIT(\"FALSE\") ) \n\t\tDCM_SP_INST (.CLKFB(CLKFB_IN), \n\t\t.CLKIN(CLKIN_IBUFG), \n\t\t.DSSEN(GND_BIT), \n\t\t.PSCLK(GND_BIT), \n\t\t.PSEN(GND_BIT), \n\t\t.PSINCDEC(GND_BIT), \n\t\t.RST(GND_BIT), \n\t\t.CLKDV(CLKDV_BUF), \n\t\t.CLKFX(CLKFX1_BUF), \n\t\t.CLKFX180(), \n\t\t.CLK0(CLK0_BUF), \n\t\t.CLK2X(), \n\t\t.CLK2X180(), \n\t\t.CLK90(), \n\t\t.CLK180(), \n\t\t.CLK270(), \n\t\t.LOCKED(DCM_SP_LOCKED_OUT), \n\t\t.PSDONE(), \n\t\t.STATUS());\n\n\tDCM_CLKGEN #(\n\t\t.CLKFX_DIVIDE(100),\t\t\t// 100Mhz osc so gives steps of 1MHz\n\t\t.CLKFX_MULTIPLY(SPEED_MHZ),\n\t\t.CLKFXDV_DIVIDE(2),\t\t\t// Unused\n\t\t.CLKIN_PERIOD(10.0),\n\t\t.CLKFX_MD_MAX(0.000),\n\t\t.SPREAD_SPECTRUM(\"NONE\"),\n\t\t.STARTUP_WAIT(\"FALSE\")\n\t\t) \n\t\tDCM_CLKGEN_INST (\n\t\t.CLKIN(CLKIN_IBUFG),\n\t\t.CLKFX(CLKFX2_BUF),\n\t\t.FREEZEDCM(1'b0),\n\t\t.PROGCLK(dcm_progclk_buf),\n\t\t.PROGDATA(dcm_progdata),\n\t\t.PROGEN(dcm_progen),\n\t\t.PROGDONE(dcm_progdone),\n\t\t.LOCKED(dcm_locked),\n\t\t.STATUS(dcm_status),\n\t\t.RST(dcm_reset)\n\t\t);\n\nendmodule\n"
  },
  {
    "path": "experimental/LX150-SLOWSIXTEEN-A/dyn_pll_ctrl.v",
    "content": "module dyn_pll_ctrl # (parameter SPEED_MHZ = 25, parameter SPEED_LIMIT = 100, parameter SPEED_MIN = 25, parameter OSC_MHZ = 100)\n\t(clk,\n\tclk_valid,\n\tspeed_in,\n\tstart,\n\tprogclk,\n\tprogdata,\n\tprogen,\n\treset,\n\tlocked,\n\tstatus);\n\n\tinput clk;\t\t\t\t// NB Assumed to be 12.5MHz uart_clk\n\tinput clk_valid;\t\t// Drive from LOCKED output of first dcm (ie uart_clk valid)\n\tinput [7:0] speed_in;\n\tinput start;\n\toutput reg progclk = 0;\n\toutput reg progdata = 0;\n\toutput reg progen = 0;\n\toutput reg reset = 0;\n\tinput locked;\n\tinput [2:1] status;\n\n\t// NB spec says to use (dval-1) and (mval-1), but I don't think we need to be that accurate\n\t//    and this saves an adder. Feel free to amend it.\n\treg [23:0] watchdog = 0;\n\treg [7:0] state = 0;\n\treg [7:0] dval = OSC_MHZ;\t// Osc clock speed (hence mval scales in MHz)\n\treg [7:0] mval = SPEED_MHZ;\n\treg start_d1 = 0;\n\t\n\talways @ (posedge clk)\n\tbegin\n\t\tprogclk <= ~progclk;\n\t\tstart_d1 <= start;\n\t\treset <= 1'b0;\n\t\t\n\t\t// Watchdog is just using locked, perhaps also need | ~status[2]\n\t\tif (locked)\n\t\t\twatchdog <= 0;\n\t\telse\n\t\t\twatchdog <= watchdog + 1'b1;\n\t\t\n\t\tif (watchdog[23])\t\t// Approx 670mS at 12.5MHz - NB spec is 5ms to lock at >50MHz CLKIN (50ms at <50MHz CLKIN)\n\t\tbegin\t\t\t\t\t// but allow longer just in case\n\t\t\twatchdog <= 0;\n\t\t\treset <= 1'b1;\t\t// One cycle at 12.5MHz should suffice (requirment is 3 CLKIN at 100MHz)\n\t\tend\n\t\t\n\t\tif (~clk_valid)\t\t\t// Try not to run while clk is unstable\n\t\tbegin\n\t\t\tprogen <= 0;\n\t\t\tprogdata <= 0;\n\t\t\tstate <= 0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\n\t\t\t// The documentation is unclear as to whether the DCM loads data on positive or negative edge. The timing\n\t\t\t// diagram unhelpfully shows data changing on the positive edge, which could mean either its sampled on\n\t\t\t// negative, or it was clocked on positive! However the following (WRONGLY) says NEGATIVE ...\n\t\t\t// http://forums.xilinx.com/t5/Spartan-Family-FPGAs/Spartan6-DCM-CLKGEN-does-PROGCLK-have-a-maximum-period-minimum/td-p/175642\n\t\t\t// BUT this can lock up the DCM, positive clock seems more reliable (but it can still lock up for low values of M, eg 2).\n\t\t\t// Added SPEED_MIN to prevent this (and positive clock is correct, after looking at other implementations eg ztex/theseven)\n\t\t\n\t\t\tif ((start || start_d1) && state==0 && speed_in >= SPEED_MIN && speed_in <= SPEED_LIMIT && progclk==1)\t// positive clock\n\t\t\t// if ((start || start_d1) && state==0 && speed_in >= SPEED_MIN && speed_in <= SPEED_LIMIT && progclk==0)\t// negative clock\n\t\t\tbegin\n\t\t\t\tprogen <= 0;\n\t\t\t\tprogdata <= 0;\n\t\t\t\tmval <= speed_in;\n\t\t\t\tdval <= OSC_MHZ;\n\t\t\t\tstate <= 1;\n\t\t\tend\n\t\t\tif (state != 0)\n\t\t\t\tstate <= state + 1'd1;\n\t\t\tcase (state)\t\t// Even values to sync with progclk\n\t\t\t\t// Send D\n\t\t\t\t2: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\t\tprogdata <= 1;\n\t\t\t\tend\n\t\t\t\t4: begin\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t6,8,10,12,14,16,18,20: begin\n\t\t\t\t\tprogdata <= dval[0];\n\t\t\t\t\tdval[6:0] <= dval[7:1];\n\t\t\t\tend\n\t\t\t\t22: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t// Send M\n\t\t\t\t32: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\t\tprogdata <= 1;\n\t\t\t\tend\n\t\t\t\t36,38,40,42,44,46,48,50: begin\n\t\t\t\t\tprogdata <= mval[0];\n\t\t\t\t\tmval[6:0] <= mval[7:1];\n\t\t\t\tend\n\t\t\t\t52: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\t\tprogdata <= 0;\n\t\t\t\tend\n\t\t\t\t// Send GO - NB 1 clock cycle\n\t\t\t\t62: begin\n\t\t\t\t\tprogen <= 1;\n\t\t\t\tend\n\t\t\t\t64: begin\n\t\t\t\t\tprogen <= 0;\n\t\t\t\tend\n\t\t\t\t// We should wait on progdone/locked, but just go straight back to idle\n\t\t\t\t254: begin\n\t\t\t\t\tstate <= 0;\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n\tend\nendmodule\n"
  },
  {
    "path": "experimental/LX150-SLOWSIXTEEN-A/ltcminer_icarus.ucf",
    "content": "# Based on https://github.com/ngzhang/Icarus/blob/master/FPGA_project/Src/fpgaminer_top.ucf\n\nNET \"hash_clk\" TNM_NET = \"hash_clk\";\nNET \"pbkdf_clk\" TNM_NET = \"pbkdf_clk\";\nNET \"uart_clk\" TNM_NET = \"uart_clk\";\n\n# 10MHz hash_clk (it may route better specifying a slightly slower clock)\nTIMESPEC TS_hash_clk = PERIOD \"hash_clk\" 10 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\n# 50MHz pbkdf_clk\nTIMESPEC TS_pbkdf_clk = PERIOD \"pbkdf_clk\" 50 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\n# 12.5MHz uart_clk\nTIMESPEC TS_uart_clk = PERIOD \"uart_clk\" 12.5 MHZ HIGH 50 % INPUT_JITTER 7 ps;\n\nNET \"osc_clk\" LOC = J1 | IOSTANDARD = LVCMOS33;\n\n# serial port receive & transmit\nNET \"RxD\" LOC = D1 | IOSTANDARD = LVCMOS33;\nNET \"TxD\" LOC = B1 | IOSTANDARD = LVCMOS33;\n\n# TTL level serial port: ja3 = rxd, ja2 = txd\nNET \"extminer_txd[0]\" LOC = D22 | IOSTANDARD = LVCMOS33;\nNET \"extminer_rxd[0]\" LOC = B22 | IOSTANDARD = LVCMOS33;\n\nNET \"led[0]\" LOC = A18 | IOSTANDARD = LVCMOS33;\nNET \"led[1]\" LOC = B18 | IOSTANDARD = LVCMOS33;\nNET \"led[2]\" LOC = A17 | IOSTANDARD = LVCMOS33;\nNET \"led[3]\" LOC = A16 | IOSTANDARD = LVCMOS33;\n\nNET \"dip[0]\" LOC = A4 | IOSTANDARD = LVCMOS33;\nNET \"dip[1]\" LOC = D6 | IOSTANDARD = LVCMOS33;\nNET \"dip[2]\" LOC = C6 | IOSTANDARD = LVCMOS33;\nNET \"dip[3]\" LOC = C8 | IOSTANDARD = LVCMOS33;\n\nNET \"TMP_SCL\" LOC = C1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_SDA\" LOC = E1 | IOSTANDARD = LVCMOS33 | PULLUP;\nNET \"TMP_ALERT\" LOC = C3 | IOSTANDARD = LVCMOS33 | PULLUP;\n"
  },
  {
    "path": "experimental/LX150-SLOWSIXTEEN-A/ltcminer_icarus.v",
    "content": "/* ltcminer_icarus.v copyright kramble 2013\n * Based on https://github.com/teknohog/Open-Source-FPGA-Bitcoin-Miner/tree/master/projects/Xilinx_cluster_cgminer\n * Hub code for a cluster of miners using async links\n * by teknohog\n */\n\n`include \"../../source/sha-256-functions.v\"\n`include \"../../source/sha256_transform.v\"\n// `include \"../../ICARUS-LX150/xilinx_pll.v\"\t// Only needed if not USE_DYN_PLL\n`include \"../../ICARUS-LX150/uart_receiver.v\"\n`include \"../../ICARUS-LX150/uart_transmitter.v\"\n`include \"../../ICARUS-LX150/serial.v\"\n`include \"../../ICARUS-LX150/serial_hub.v\"\n`include \"../../ICARUS-LX150/hub_core.v\"\n`include \"../../ICARUS-LX150/pwm_fade.v\"\n\nmodule ltcminer_icarus (osc_clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n// NB SPEED_MHZ resolution is 5MHz steps to keep pll divide ratio sensible. Change the divider in xilinx_pll.v if you\n// want other steps (1MHz is not sensible as it requires divide 100 which is not in the allowed range 1..32 for DCM_SP)\n// New dyn_pll has 1MHz resolution and can be changed by sending a specific getwork packet (uses top bytes of target)\n\n`define USE_DYN_PLL\t\t// Enable new dyn_pll\n\n`ifdef SPEED_MHZ\n\tparameter SPEED_MHZ = `SPEED_MHZ;\n`else\n\tparameter SPEED_MHZ = 40;\t\t\t\t\t\t// Default to slow, use dynamic config to ramp up in realtime\n`endif\n\n`ifdef SPEED_LIMIT\n\tparameter SPEED_LIMIT = `SPEED_LIMIT;\t\t\t// Fastest speed accepted by dyn_pll config\n`else\n\tparameter SPEED_LIMIT = 100;\t\t\t\t\t// Deliberately conservative, increase at own risk\n`endif\n\n`ifdef SPEED_MIN\n\tparameter SPEED_MIN = `SPEED_MIN;\t\t\t\t// Slowest speed accepted by dyn_pll config (CARE can lock up if too low)\n`else\n\tparameter SPEED_MIN = 10;\n`endif\n\n`ifdef SERIAL_CLK\n\tparameter comm_clk_frequency = `SERIAL_CLK;\n`else\n\tparameter comm_clk_frequency = 12_500_000;\t\t// 100MHz divide 8\n`endif\n\n`ifdef BAUD_RATE\n\tparameter BAUD_RATE = `BAUD_RATE;\n`else\n\tparameter BAUD_RATE = 115_200;\n`endif\n\n// kramble - nonce distribution is crude using top 4 bits of nonce so max LOCAL_MINERS = 8\n// teknohog's was more sophisticated, but requires modification of hashcore.v\n\n// Miners on the same FPGA with this hub\n`ifdef LOCAL_MINERS\n\tparameter LOCAL_MINERS = `LOCAL_MINERS;\n`else\n\tparameter LOCAL_MINERS = 2;\t\t\t\t\t\t// One to four cores (configures ADDRBITS automatically)\n`endif\n\n`ifdef ADDRBITS\n\tparameter ADDRBITS = `ADDRBITS;\t\t\t\t\t// Override for simulation or a quick ISE build (eg one 10 bit core)\n`else\n\tparameter ADDRBITS = 12 - clog2(LOCAL_MINERS);\t// Automatically selects largest RAM that will fit LX150\n`endif\n\n// kramble - nonce distribution only works for a single external port \n`ifdef EXT_PORTS\n\tparameter EXT_PORTS = `EXT_PORTS;\n`else\n\tparameter EXT_PORTS = 1;\n`endif\n\n\tlocalparam SLAVES = LOCAL_MINERS + EXT_PORTS;\n\n\tinput osc_clk;\n\twire hash_clk, uart_clk, pbkdf_clk;\n\n`ifdef USE_DYN_PLL\n\twire first_dcm_locked, dcm_progclk, dcm_progdata, dcm_progen, dcm_reset, dcm_progdone, dcm_locked;\n\twire [2:1] dcm_status;\n`endif\n\n`ifndef SIM\n\t`ifdef USE_DYN_PLL\n\t\tdyn_pll # (.SPEED_MHZ(SPEED_MHZ)) dyn_pll_blk\n\t\t\t(osc_clk, \n\t\t\tpbkdf_clk, \n\t\t\thash_clk, \n\t\t\tuart_clk,\n\t\t\tfirst_dcm_locked,\n\t\t\tdcm_progclk,\n\t\t\tdcm_progdata,\n\t\t\tdcm_progen,\n\t\t\tdcm_reset,\n\t\t\tdcm_progdone,\n\t\t\tdcm_locked,\n\t\t\tdcm_status);\n\t`else\n\t\tmain_pll # (.SPEED_MHZ(SPEED_MHZ)) pll_blk (.CLKIN_IN(osc_clk), .CLKFX_OUT(hash_clk), .CLKDV_OUT(uart_clk));\n\t\tassign pbkdf_clk = uart_clk;\n\t`endif\n`else\n\tassign hash_clk = osc_clk;\n\tassign uart_clk = osc_clk;\n\tassign pbkdf_clk = osc_clk;\n\t`ifdef USE_DYN_PLL\n\t\tassign first_dcm_locked = 1'b1;\n\t\tassign dcm_progdone = 1'b1;\n\t\tassign dcm_locked = 1'b1;\n\t\tassign dcm_status = 0;\n\t`endif\t\n`endif\n\n`ifdef USE_DYN_PLL\n\treg [7:0] dyn_pll_speed = SPEED_MHZ;\n\treg dyn_pll_start = 0;\n\tparameter OSC_MHZ = 100;\t\t// Clock oscillator (used for divider ratio)\n\tdyn_pll_ctrl # (.SPEED_MHZ(SPEED_MHZ), .SPEED_LIMIT(SPEED_LIMIT), .SPEED_MIN(SPEED_MIN), .OSC_MHZ(OSC_MHZ)) dyn_pll_ctrl_blk\n\t\t(uart_clk,\t\t\t// NB uses uart_clk as its just osc/8 and should always be valid\n\t\tfirst_dcm_locked,\t// ... but we check it anyway\n\t\tdyn_pll_speed,\n\t\tdyn_pll_start,\n\t\tdcm_progclk,\n\t\tdcm_progdata,\n\t\tdcm_progen,\n\t\tdcm_reset,\n\t\tdcm_locked,\n\t\tdcm_status);\n`endif\n      \n\tinput TMP_SCL, TMP_SDA, TMP_ALERT;\t// Unused but set to PULLUP so as to avoid turning on the HOT LED\n\t\t\t\t\t\t\t\t\t\t// TODO implement I2C protocol to talk to temperature sensor chip (TMP101?)\n\t\t\t\t\t\t\t\t\t\t// and drive FAN speed control output.\n\n\tinput [3:0]dip;\n\twire reset, nonce_chip;\n\tassign reset = dip[0];\t\t\t// Not used\n\tassign nonce_chip = dip[1];\t\t// Distinguishes between the two Icarus FPGA's\n\n\t// Work distribution is simply copying to all miners, so no logic\n\t// needed there, simply copy the RxD.\n\tinput\tRxD;\n\toutput\tTxD;\n\n\t// Results from the input buffers (in serial_hub.v) of each slave\n\twire [SLAVES*32-1:0]\tslave_nonces;\n\twire [SLAVES*32-1:0]\tslave_debug_sr;\n\twire [SLAVES-1:0]\t\tnew_nonces;\n\n\t// Using the same transmission code as individual miners from serial.v\n\twire\t\tserial_send;\n\twire\t\tserial_busy;\n\twire [31:0]\tgolden_nonce;\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) sertx (.clk(uart_clk), .TxD(TxD), .send(serial_send), .busy(serial_busy), .word(golden_nonce));\n\n\thub_core #(.SLAVES(SLAVES)) hc (.uart_clk(uart_clk), .new_nonces(new_nonces), .golden_nonce(golden_nonce), .serial_send(serial_send), .serial_busy(serial_busy), .slave_nonces(slave_nonces));\n\n\t// Common workdata input for local miners\n\twire [255:0]\tdata1, data2;\n\twire [127:0]\tdata3;\n\twire [31:0]\t\ttarget;\n\treg  [31:0]\t\ttargetreg = 32'h000007ff;\t// Start at sane value (overwritten by serial_receive)\n\twire\t\t\trx_done;\t\t// Signals hashcore to reset the nonce\n\t\t\t\t\t\t\t\t\t// NB in my implementation, it loads the nonce from data3 which should be fine as\n\t\t\t\t\t\t\t\t\t// this should be zero, but also supports testing using non-zero nonces.\n\n\t// Synchronise across clock domains from uart_clk to hash_clk\n\t// This probably looks amateurish (mea maxima culpa, novice verilogger at work), but should be OK\n\treg rx_done_toggle = 1'b0;\t\t// uart_clk domain\n\talways @ (posedge uart_clk)\n\t\trx_done_toggle <= rx_done_toggle ^ rx_done;\n\n\treg rx_done_toggle_d1 = 1'b0;\t// hash_clk domain\n\treg rx_done_toggle_d2 = 1'b0;\n\treg rx_done_toggle_d3 = 1'b0;\n\t\n\twire loadnonce;\n\tassign loadnonce = rx_done_toggle_d3 ^ rx_done_toggle_d2;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\trx_done_toggle_d1 <= rx_done_toggle;\n\t\trx_done_toggle_d2 <= rx_done_toggle_d1;\n\t\trx_done_toggle_d3 <= rx_done_toggle_d2;\n\t\tif (loadnonce)\n\t\t\ttargetreg <= target;\n\tend\n\t// End of clock domain sync\n\n\twire [31:0] mod_target;\n\n`ifdef USE_DYN_PLL\n\t// Top byte of target is clock multiplier, 2nd byte is validation (one's complement of clock multiplier)\n\t// These bytes are always zero in normal getwork, so we now hard code in mod_target and use them to set clock speed.\n\t// NB The pll controller is in uart_clk domain so use serial_receive signals directly\n\t// wire [7:0]invtarg;\t\t\t\t\t// Just checking the syntax in simulator, DELETE\n\t// assign invtarg = ~target[24:16];\n\talways @ (posedge uart_clk)\n\tbegin\n\t\tdyn_pll_start <= 0;\n\t\t// A sanity check to reduce the risk of speed being set to garbage\n\t\t// Top byte of target is speed, second byte MUST be its inverse, and neither must be zero (which also rules out all ones)\n\t\tif (rx_done && target[31:24] != dyn_pll_speed && target[31:24] != 0 && target[23:16] != 0 && target[31:24] == ~target[23:16])\n\t\t// if (rx_done && target[31:24] != dyn_pll_speed && target[31:24] != 0)\t// Simpler version for DEBUG, does no verification\n\t\tbegin\n\t\t\tdyn_pll_speed <= target[31:24];\n\t\t\tdyn_pll_start <= 1;\n\t\tend\n\tend\n\tassign mod_target = { 16'd0, targetreg[15:0] };\t// Ignore top two bytes\n`else\n\t// Its better to always hard-wire the 16 MSB to zero ... if comms noise sets these bits it completely de-syncs,\n\t// generating a continuous stream of golden_nonces overwhelming the python driver which can't then reset the target.\n\t// assign mod_target = targetreg;\t\t\t\t// Original 32 bit target\n\tassign mod_target = { 16'd0, targetreg[15:0] };\t// Ignore top two bytes\n`endif\n\t\n\tserial_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) serrx (.clk(uart_clk), .RxD(RxD), .data1(data1),\n\t\t\t\t\t\t.data2(data2), .data3(data3), .target(target), .rx_done(rx_done));\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\n\t// Local miners now directly connected\n\tgenerate\n\t\tgenvar i;\n\t\tfor (i = 0; i < LOCAL_MINERS; i = i + 1)\n\t\t// begin: for_local_miners ... too verbose, so...\n\t\tbegin: miners\n\t\t\twire [31:0] nonce_out;\t// Not used\n\t\t\twire [2:0] nonce_core = i;\n\t\t\twire gn_match;\n\t\t\twire salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift;\n\t\t\twire [SBITS-1:0] salsa_din;\n\t\t\twire [SBITS-1:0] salsa_dout;\n\t\t\twire [3:0] dummy;\t// So we can ignore top 4 bits of slave_debug_sr\n\n\t\t\t// Currently one pbkdfengine per salsaengine - TODO share the pbkdfengine for several salsaengines\n\t\t\tpbkdfengine #(.SBITS(SBITS)) P\n\t\t\t\t(.hash_clk(hash_clk), .pbkdf_clk(pbkdf_clk), .data1(data1), .data2(data2), .data3(data3), .target(mod_target),\n\t\t\t\t.nonce_msb({nonce_chip, nonce_core}), .nonce_out(nonce_out), .golden_nonce_out(slave_nonces[i*32+31:i*32]),\n\t\t\t\t.golden_nonce_match(gn_match), .loadnonce(loadnonce),\n\t\t\t\t.salsa_din(salsa_din), .salsa_dout(salsa_dout), .salsa_busy(salsa_busy), .salsa_result(salsa_result),\n\t\t\t\t.salsa_reset(salsa_reset), .salsa_start(salsa_start), .salsa_shift(salsa_shift));\n\n\t\t\tsalsaengine #(.ADDRBITS(ADDRBITS), .SBITS(SBITS)) S\n\t\t\t\t(.hash_clk(hash_clk), .reset(salsa_reset), .din(salsa_din), .dout(salsa_dout),\n\t\t\t\t.shift(salsa_shift), .start(salsa_start), .busy(salsa_busy), .result(salsa_result) );\n\t\t\t\t\t\n\t\t\t// Synchronise across clock domains from pbkdf_clk to uart_clk for: assign new_nonces[i] = gn_match;\n\t\t\treg gn_match_toggle = 1'b0;\t\t// hash_clk domain\n\t\t\talways @ (posedge pbkdf_clk)\n\t\t\t\tgn_match_toggle <= gn_match_toggle ^ gn_match;\n\n\t\t\treg gn_match_toggle_d1 = 1'b0;\t// uart_clk domain\n\t\t\treg gn_match_toggle_d2 = 1'b0;\n\t\t\treg gn_match_toggle_d3 = 1'b0;\n\n\t\t\tassign new_nonces[i] = gn_match_toggle_d3 ^ gn_match_toggle_d2;\n\n\t\t\talways @ (posedge uart_clk)\n\t\t\tbegin\n\t\t\t\tgn_match_toggle_d1 <= gn_match_toggle;\n\t\t\t\tgn_match_toggle_d2 <= gn_match_toggle_d1;\n\t\t\t\tgn_match_toggle_d3 <= gn_match_toggle_d2;\n\t\t\tend\n\t\t\t// End of clock domain sync\n\t\tend // for\n\tendgenerate\n\n\t// External miner ports, results appended to the same\n\t// slave_nonces/new_nonces as local ones\n\toutput [EXT_PORTS-1:0] extminer_txd;\n\tinput [EXT_PORTS-1:0]  extminer_rxd;\n\t// wire [EXT_PORTS-1:0]  extminer_rxd_debug = 1'b1;\t// DISABLE INPUT\n\tassign extminer_txd = {EXT_PORTS{RxD}};\n\n\tgenerate\n\t\tgenvar j;\n\t\tfor (j = LOCAL_MINERS; j < SLAVES; j = j + 1)\n\t\t// begin: for_ports ... too verbose, so ...\n\t\tbegin: ports\n\t\t\tslave_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) slrx (.clk(uart_clk), .RxD(extminer_rxd[j-LOCAL_MINERS]), .nonce(slave_nonces[j*32+31:j*32]), .new_nonce(new_nonces[j]));\n\t\tend\n\tendgenerate\n\n\toutput [3:0] led;\n\tassign led[1] = ~RxD;\n\t// assign led[2] = ~TxD;\n\t// assign led[3] = ~ (TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED - held low (the TMP pins are PULLUP, this is a fudge to\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// avoid warning about unused inputs)\n\t\n\tassign led[3] = ~first_dcm_locked | ~dcm_locked | dcm_status[2] | ~(TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED now dcm status\n\n`define FLASHCLOCK\t\t// Gives some feedback as the the actual clock speed\n\n`ifdef FLASHCLOCK\n\treg [26:0] hash_count = 0;\n\treg [3:0] sync_hash_count = 0;\n\talways @ (posedge uart_clk)\n\t\tif (rx_done)\n\t\t\tsync_hash_count[0] <= ~sync_hash_count[0];\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tsync_hash_count[3:1] <= sync_hash_count[2:0];\n\t\thash_count <= hash_count + 1'b1;\n\t\tif (sync_hash_count[3] != sync_hash_count[2])\n\t\t\thash_count <= 0;\n\tend\n\tassign led[2] = hash_count[26];\n`else\n\tassign led[2] = ~TxD;\n`endif\n\n\t// Light up only from locally found nonces, not ext_port results\n\tpwm_fade pf (.clk(uart_clk), .trigger(|new_nonces[LOCAL_MINERS-1:0]), .drive(led[0]));\n   \nendmodule\n"
  },
  {
    "path": "experimental/LX150-SLOWSIXTEEN-A/pbkdfengine.v",
    "content": "/* pbkdfengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`define ICARUS\t\t\t// Comment this out when using the altera virtual_wire interface in ltcminer.v\n\t\n`timescale 1ns/1ps\n\nmodule pbkdfengine\n\t(hash_clk, pbkdf_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce,\n\t\t\tsalsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift);\n\n\tinput hash_clk;\t\t\t// Just drives shift register\n\tinput pbkdf_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\n\toutput [31:0] nonce_out;\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] salsa_dout;\n\toutput [SBITS-1:0] salsa_din;\n\n\tinput salsa_busy, salsa_result;\t// NB hash_clk domain\n\toutput salsa_reset;\n\toutput salsa_start;\n\toutput reg salsa_shift = 1'b0;\t// NB hash_clk domain\n\n\treg [4:0]resetcycles = 5'd0;\n\treg reset = 1'b0;\n\tassign salsa_reset = reset;\t\t// Propagate reset to salsaengine\n\n`ifdef WANTCYCLICRESET\t\t\n\treg [23:0]cycresetcount = 24'd0;\n`endif\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\t// Hard code a 24 cycle reset (NB assumes THREADS=16 in salsaengine, else we need more)\n\t\t// NB hash_clk is faster than pbkdf_clk so the salsaengine will actually be initialised well before\n\t\t// this period ends, but keep to 24 for now as simulation uses equal pbkdf and salsa clock speeds.\n\t\tresetcycles <= resetcycles + 1'd1;\n\t\tif (resetcycles == 5'd0)\n\t\t\treset <= 1'b1;\n\t\tif (resetcycles == 5'd24)\n\t\tbegin\n\t\t\treset <= 1'b0;\n\t\t\tresetcycles <= 5'd24;\n\t\tend\n`ifdef WANTCYCLICRESET\t\t\n\t\t// Cyclical reset every 2_500_000 clocks to ensure salsa pipeline does not drift out of sync\n\t\t// This may be unneccessary if we reset every loadnonce\n\t\t// Actually it seems to do more harm than good, so disabled\n\t\tcycresetcount <= cycresetcount + 1'd1;\n\t\tif (cycresetcount == 2_500_000)\t// 10 per second at 25MHz (adjust as neccessary)\n\t\tbegin\n\t\t\tcycresetcount <= 24'd0;\n\t\t\tresetcycles <= 5'd0;\n\t\tend\n`endif\t\t\n\t\t// Reset on loadnonce (the hash results will be junk anyway since data changes, so no loss of shares)\n\t\tif (loadnonce)\n\t\t\tresetcycles <= 5'd0;\n\tend\n\t\n\t`ifndef ICARUS\n\treg [31:0] nonce_previous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\t`endif\n\n\t`ifndef NOMULTICORE\n\t`ifdef SIM\n\t\treg [27:0] nonce_cnt = 28'h318f;\t// Start point for simulation (NB also define SIM in serial.v)\n\t`else\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t`endif\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\tassign nonce_out = nonce;\n\n\treg [31:0] nonce_sr = 32'd0;\t\t// Nonce is shifted to salsaengine for storage/retrieval (hash_clk domain)\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\treg [2:0] nonce_wait = 3'd0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [2:0] blockcnt = 3'd0;\t\t// Takes values 1..5 for block iteration\n\treg [1023:0] Xbuf = 1024'd0;\t// Shared input/output buffer and shift register (hash_clk domain)\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\tassign salsa_din = Xbuf[1023:1024-SBITS];\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\t\n\t// MixOut is little-endian word format to match scrypt.c so convert back to big-endian\n\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] mix;\n\t\tassign mix = Xbuf[`IDX(i)];\t\t// NB MixOut now shares Xbuf since shifted in/out\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\n\t// Interface control. This should be OK provided the threads remain evenly spaced (hence we reset on loadnonce)\n\t\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\treg Clr_SMixOutRdy = 1'b0;\n\twire Clr_SMixInRdy;\n\twire Set_SMixOutRdy;\n\n\treg [4:0]salsa_busy_d = 0;\t\t\t// Sync to pbkdf_clk domain\n\treg [4:0]salsa_result_d = 0;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\t// Sync to pbkdf_clk domain\n\t\tsalsa_busy_d[0] <= salsa_busy;\n\t\tif (salsa_busy & ~ salsa_busy_d[0])\n\t\t\tsalsa_busy_d[1] <= ~ salsa_busy_d[1];\t\t// Toggle on busy going high\n\t\t\n\t\tsalsa_result_d[0] <= salsa_result;\n\t\tif (salsa_result & ~ salsa_result_d[0])\n\t\t\tsalsa_result_d[1] <= ~ salsa_result_d[1];\t// Toggle on result going high\n\tend\n\t\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tsalsa_busy_d[4:2] <= salsa_busy_d[3:1];\n\t\tsalsa_result_d[4:2] <= salsa_result_d[3:1];\n\t\t\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\t\t\t\n\t\t// CARE there is a race with Set_SMixInRdy, Clr_SMixOutRdy which are set in the FSM\n\t\t// Need to assert reset for several cycles to ensure consistency (acutally use 15 since salsaengine needs more)\n\t\tif (reset)\n\t\tbegin\t\t\t\t\t\t\t// Reset takes priority\n\t\t\tSMixInRdy_state <= 1'b0;\n\t\t\tSMixOutRdy_state <= 1'b0;\n\t\tend\n\tend\n\t\n\tassign Clr_SMixInRdy = SMixInRdy_state & (salsa_busy_d[3] ^ salsa_busy_d[4]);\t\t\t// Clear on transition to busy\n\t\n\tassign Set_SMixOutRdy = ~SMixOutRdy_state & (salsa_result_d[3] ^ salsa_result_d[4]);\t// Set on transition to result\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\tassign salsa_start = SMixInRdy;\n\t\t\n\t// Clock crossing flags for shift register control (span pbkdf_clk, hash_clk domains)\n\treg [3:0]Xbuf_load_request = 1'b0;\n\treg [3:0]shift_request =  1'b0;\n\treg [3:0]shift_acknowledge = 1'b0;\n\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz)\n\t\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_NONCE=22, S_SHIFT_IN=41, S_SHIFT_OUT=42,\t\t\t\t// Direction relative to salsa unit\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\treg start_output = 0;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\n\t\tshift_acknowledge[3:1] <= shift_acknowledge[2:0];\t// Clock crossing\n\n\t\t`ifdef ICARUS\n\t\tif (loadnonce)\t\t\t\t// Separate clock domains means comparison is unsafe\n\t\t`else\n\t\tif (loadnonce || (nonce_previous_load != data3[127:96]))\n\t\t`endif\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_previous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\t`ifndef ICARUS\n\t\t\tnonce_previous_load <= data3[127:96];\n\t\t\t`endif\n\t\tend\n\t\t\n\t\tif (reset == 1'b1)\n\t\tbegin\n\t\t\tstate <= S_IDLE;\n\t\t\tstart_output <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tif (SMixOutRdy & ~start_output)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\t// Request shifter to start\n\t\t\t\t\t\tstate <= S_SHIFT_OUT;\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (start_output ||\t// Process output\n\t\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'b0;\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\t\tblockcnt <= 3'd1;\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_sr : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\t\t\n\t\t\t\tS_B6: begin\n\t\t\t\t\t\tkhash <= tx_hash;\t\t// Save temporarily (for Xbuf)\n\n\t\t\t\t\t\tXbuf_load_request[0] <= ~Xbuf_load_request[0];\t// NB also loads nonce_sr\n\n\t\t\t\t\t\tif (blockcnt == 3'd5)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tnonce_wait <= 3'd7;\n\t\t\t\t\t\t\tstate <= S_NONCE;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_NONCE: begin\n\t\t\t\t\t\t// Need to delay a few clocks for Xbuf_load_request to complete\n\t\t\t\t\t\tnonce_wait <= nonce_wait - 1'd1;\n\t\t\t\t\t\tif (nonce_wait == 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 1'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 1'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\n\t\t\t\t\t\t\tstate <= S_SHIFT_IN;\n\t\t\t\t\t\tend\n\t\t\t\t\n\t\t\t\tend\n\t\t\t\tS_SHIFT_IN: begin\t\t\t\t\t\t\t// Shifting from PBKDF2_SHA256 to salsa\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tSet_SMixInRdy <= 1'd1;\t\t\t\t// Flag salsa to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_SHIFT_OUT: begin\t\t\t\t\t\t\t// Shifting from salsa to PBKDF2_SHA256\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'd1;\t\t\t\t// Flag self to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_sr;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (state==S_R18)\n\t\t$display (\"final_hash %x\\n\", tx_hash);\n`endif\n\tend\n\n\t// Shift register control - NB hash_clk domain\n\t\n\treg\t[10:0]shift_count = 11'd0;\t// hash_clk domain\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tif (reset)\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b0;\n\t\t\tshift_count <= 11'd0;\n\t\tend\n\n\t\t// Clock crossing logic\n\t\tXbuf_load_request[3:1] <= Xbuf_load_request[2:0];\n\t\tif (Xbuf_load_request[3] != Xbuf_load_request[2])\n\t\tbegin\n\t\t\t// Shift output into X buffer from MSB->LSB\n\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\tXbuf[1023:768] <= khash;\n\n\t\t\tnonce_sr <= nonce;\t// Loaded several times, but of no consequence\n\t\tend\n\t\t\n\t\tshift_request[3:1] <= shift_request[2:0];\n\t\tif (shift_request[3] != shift_request[2])\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b1;\n\t\tend\n\n\t\tif (salsa_shift)\n\t\tbegin\n\t\t\tshift_count <= shift_count + 1'b1;\n\t\t\tXbuf <= { Xbuf[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], salsa_dout };\n\t\tend\n\t\t\n\t\tif (shift_count == (1024+32)/SBITS-1)\n\t\tbegin\n\t\t\tshift_acknowledge[0] = ~shift_acknowledge[0];\n\t\t\tshift_count <= 0;\n\t\t\tsalsa_shift <= 0;\n\t\tend\n\tend\n\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(pbkdf_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\nendmodule"
  },
  {
    "path": "experimental/LX150-SLOWSIXTEEN-A/salsa_slowsixteen.v",
    "content": "/* salsa_slowsixteen.v\n*\n* Copyright (c) 2013 kramble\n* Derived from scrypt.c Copyright 2009 Colin Percival, 2011 ArtForz\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\nmodule salsa (clk, B, Bx, Bo, X0out, Xaddr);\n\n// Latency 16 clock cycles, approx 20nS propagation delay (SLOW!)\n\ninput clk;\n// input feedback;\ninput [511:0]B;\ninput [511:0]Bx;\n// output reg [511:0]Bo;\t// Output is registered\noutput [511:0]Bo;\t\t\t// Output is async\noutput [511:0]X0out;\t\t// Becomes new X0\noutput [9:0] Xaddr;\nwire [9:0] xa1, xa2, xa3, xa4, ya1, ya2, ya3, ya4;\n\nreg [511:0]x1d1, x1d1a;\nreg [511:0]x1d2, x1d2a;\nreg [511:0]x1d3, x1d3a;\nreg [511:0]x1d4, x1d4a;\n\nreg [511:0]Xod1, Xod1a;\nreg [511:0]Xod2, Xod2a;\nreg [511:0]Xod3, Xod3a;\nreg [511:0]Xod4, X0out;\n\nreg [511:0]xxd1, xxd1a;\nreg [511:0]xxd2, xxd2a;\nreg [511:0]xxd3, xxd3a;\nreg [511:0]xxd4, xxd4a;\n\nreg [511:0]yyd1, yyd1a;\nreg [511:0]yyd2, yyd2a;\nreg [511:0]yyd3, yyd3a;\nreg [511:0]yyd4, yyd4a;\n\nwire [511:0]xx;\t\t\t// Initial xor\nwire [511:0]x1;\t\t\t// Salasa core outputs\nwire [511:0]x2;\nwire [511:0]x3;\nwire [511:0]xr;\nwire [511:0]Xo;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsax1 (clk, xx, x1, xa1);\nsalsa_core salsax2 (clk, x1, x2, xa2);\nsalsa_core salsax3 (clk, x2, x3, xa3);\nsalsa_core salsax4 (clk, x3, xr, xa4);\n\nwire [511:0]yy;\t\t\t// Initial xor\nwire [511:0]y1;\t\t\t// Salasa core outputs\nwire [511:0]y2;\nwire [511:0]y3;\nwire [511:0]yr;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsay1 (clk, yy, y1, ya1);\nsalsa_core salsay2 (clk, y1, y2, ya2);\nsalsa_core salsay3 (clk, y2, y3, ya3);\nsalsa_core salsay4 (clk, y3, yr, ya4);\n\nassign Xaddr = yyd4[9:0] + ya4;\n\ngenvar i;\ngenerate\n\tfor (i = 0; i < 16; i = i + 1) begin : XX\n\t\t// Initial XOR. NB this adds to the propagation delay of the first salsa, may want register it.\n\t\tassign xx[`IDX(i)] = B[`IDX(i)] ^ Bx[`IDX(i)];\n\t\tassign Xo[`IDX(i)] = xxd4a[`IDX(i)] + xr[`IDX(i)];\n\t\tassign yy[`IDX(i)] = x1d4a[`IDX(i)] ^ Xo[`IDX(i)];\n\t\tassign Bo[`IDX(i)] = yyd4a[`IDX(i)] + yr[`IDX(i)];\t// Async output\n\tend\nendgenerate\n\nalways @ (posedge clk)\nbegin\n\tx1d1 <= Bx;\n\tx1d1a <= x1d1;\n\tx1d2 <= x1d1a;\n\tx1d2a <= x1d2;\n\tx1d3 <= x1d2a;\n\tx1d3a <= x1d3;\n\tx1d4 <= x1d3a;\n\tx1d4a <= x1d4;\n\tXod1 <= Xo;\n\tXod1a <= Xod1;\n\tXod2 <= Xod1a;\n\tXod2a <= Xod2;\n\tXod3 <= Xod2a;\n\tXod3a <= Xod3;\n\tXod4 <= Xod3a;\n\tX0out <= Xod4;\t// We output this to become new X0\n\n\txxd1 <= xx;\n\txxd1a <= xxd1;\n\txxd2 <= xxd1a;\n\txxd2a <= xxd2;\n\txxd3 <= xxd2a;\n\txxd3a <= xxd3;\n\txxd4 <= xxd3a;\n\txxd4a <= xxd4;\n\n\tyyd1 <= yy;\n\tyyd1a <= yyd1;\n\tyyd2 <= yyd1a;\n\tyyd2a <= yyd2;\n\tyyd3 <= yyd2a;\n\tyyd3a <= yyd3;\n\tyyd4 <= yyd3a;\n\tyyd4a <= yyd4;\n\nend\n\nendmodule\n\nmodule salsa_core (clk, xx, out, Xaddr);\n\ninput clk;\ninput [511:0]xx;\noutput reg [511:0]out;\t\t// Output is registered\noutput [9:0] Xaddr;\t\t\t// Address output unregistered\n\n// This is clunky due to my lack of verilog skills but it works so elegance can come later\n\nwire [31:0]c00;\t\t\t// Column results\nwire [31:0]c01;\nwire [31:0]c02;\nwire [31:0]c03;\nwire [31:0]c04;\nwire [31:0]c05;\nwire [31:0]c06;\nwire [31:0]c07;\nwire [31:0]c08;\nwire [31:0]c09;\nwire [31:0]c10;\nwire [31:0]c11;\nwire [31:0]c12;\nwire [31:0]c13;\nwire [31:0]c14;\nwire [31:0]c15;\n\nwire [31:0]r00;\t\t\t// Row results\nwire [31:0]r01;\nwire [31:0]r02;\nwire [31:0]r03;\nwire [31:0]r04;\nwire [31:0]r05;\nwire [31:0]r06;\nwire [31:0]r07;\nwire [31:0]r08;\nwire [31:0]r09;\nwire [31:0]r10;\nwire [31:0]r11;\nwire [31:0]r12;\nwire [31:0]r13;\nwire [31:0]r14;\nwire [31:0]r15;\n\nwire [31:0]c00s;\t\t\t// Column sums\nwire [31:0]c01s;\nwire [31:0]c02s;\nwire [31:0]c03s;\nwire [31:0]c04s;\nwire [31:0]c05s;\nwire [31:0]c06s;\nwire [31:0]c07s;\nwire [31:0]c08s;\nwire [31:0]c09s;\nwire [31:0]c10s;\nwire [31:0]c11s;\nwire [31:0]c12s;\nwire [31:0]c13s;\nwire [31:0]c14s;\nwire [31:0]c15s;\n\nwire [31:0]r00s;\t\t\t// Row sums\nwire [31:0]r01s;\nwire [31:0]r02s;\nwire [31:0]r03s;\nwire [31:0]r04s;\nwire [31:0]r05s;\nwire [31:0]r06s;\nwire [31:0]r07s;\nwire [31:0]r08s;\nwire [31:0]r09s;\nwire [31:0]r10s;\nwire [31:0]r11s;\nwire [31:0]r12s;\nwire [31:0]r13s;\nwire [31:0]r14s;\nwire [31:0]r15s;\n\nreg [31:0]c00d;\t\t\t// Column results registered\nreg [31:0]c01d;\nreg [31:0]c02d;\nreg [31:0]c03d;\nreg [31:0]c04d;\nreg [31:0]c05d;\nreg [31:0]c06d;\nreg [31:0]c07d;\nreg [31:0]c08d;\nreg [31:0]c09d;\nreg [31:0]c10d;\nreg [31:0]c11d;\nreg [31:0]c12d;\nreg [31:0]c13d;\nreg [31:0]c14d;\nreg [31:0]c15d;\n\n/* From scrypt.c\n\n#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))\n\tfor (i = 0; i < 8; i += 2) {\n\t\t// Operate on columns\n\t\tx04 ^= R(x00+x12, 7);\tx09 ^= R(x05+x01, 7);\tx14 ^= R(x10+x06, 7);\tx03 ^= R(x15+x11, 7);\n\t\tx08 ^= R(x04+x00, 9);\tx13 ^= R(x09+x05, 9);\tx02 ^= R(x14+x10, 9);\tx07 ^= R(x03+x15, 9);\n\t\tx12 ^= R(x08+x04,13);\tx01 ^= R(x13+x09,13);\tx06 ^= R(x02+x14,13);\tx11 ^= R(x07+x03,13);\n\t\tx00 ^= R(x12+x08,18);\tx05 ^= R(x01+x13,18);\tx10 ^= R(x06+x02,18);\tx15 ^= R(x11+x07,18);\n\n\t\t// Operate on rows\n\t\tx01 ^= R(x00+x03, 7);\tx06 ^= R(x05+x04, 7);\tx11 ^= R(x10+x09, 7);\tx12 ^= R(x15+x14, 7);\n\t\tx02 ^= R(x01+x00, 9);\tx07 ^= R(x06+x05, 9);\tx08 ^= R(x11+x10, 9);\tx13 ^= R(x12+x15, 9);\n\t\tx03 ^= R(x02+x01,13);\tx04 ^= R(x07+x06,13);\tx09 ^= R(x08+x11,13);\tx14 ^= R(x13+x12,13);\n\t\tx00 ^= R(x03+x02,18);\tx05 ^= R(x04+x07,18);\tx10 ^= R(x09+x08,18);\tx15 ^= R(x14+x13,18);\n\t}\n*/\n\n// cols\n\nassign c04s = xx[`IDX(0)] + xx[`IDX(12)];\nassign c04 = xx[`IDX(4)] ^ { c04s[24:0], c04s[31:25] };\nassign c09s = xx[`IDX(5)] + xx[`IDX(1)];\nassign c09 = xx[`IDX(9)] ^ { c09s[24:0], c09s[31:25] };\nassign c14s = xx[`IDX(10)] + xx[`IDX(6)];\nassign c14 = xx[`IDX(14)] ^ { c14s[24:0], c14s[31:25] };\nassign c03s = xx[`IDX(15)] + xx[`IDX(11)];\nassign c03 = xx[`IDX(03)] ^ { c03s[24:0], c03s[31:25] };\n\nassign c08s = c04 + xx[`IDX(0)];\nassign c08 = xx[`IDX(8)] ^ { c08s[22:0], c08s[31:23] };\nassign c13s = c09 + xx[`IDX(5)];\nassign c13 = xx[`IDX(13)] ^ { c13s[22:0], c13s[31:23] };\nassign c02s = c14 + xx[`IDX(10)];\nassign c02 = xx[`IDX(2)] ^ { c02s[22:0], c02s[31:23] };\nassign c07s = c03 + xx[`IDX(15)];\nassign c07 = xx[`IDX(7)] ^ { c07s[22:0], c07s[31:23] };\n\nassign c12s = c08 + c04;\nassign c12 = xx[`IDX(12)] ^ { c12s[18:0], c12s[31:19] };\nassign c01s = c13 + c09;\nassign c01 = xx[`IDX(1)] ^ { c01s[18:0], c01s[31:19] };\nassign c06s = c02 + c14;\nassign c06 = xx[`IDX(6)] ^ { c06s[18:0], c06s[31:19] };\nassign c11s = c07 + c03;\nassign c11 = xx[`IDX(11)] ^ { c11s[18:0], c11s[31:19] };\n\nassign c00s = c12 + c08;\nassign c00 = xx[`IDX(0)] ^ { c00s[13:0], c00s[31:14] };\nassign c05s = c01 + c13;\nassign c05 = xx[`IDX(5)] ^ { c05s[13:0], c05s[31:14] };\nassign c10s = c06 + c02;\nassign c10 = xx[`IDX(10)] ^ { c10s[13:0], c10s[31:14] };\nassign c15s = c11 + c07;\nassign c15 = xx[`IDX(15)] ^ { c15s[13:0], c15s[31:14] };\n\n// rows\n\nassign r01s = c00d + c03d;\nassign r01 = c01d ^ { r01s[24:0], r01s[31:25] };\nassign r06s = c05d + c04d;\nassign r06 = c06d ^ { r06s[24:0], r06s[31:25] };\nassign r11s = c10d + c09d;\nassign r11 = c11d ^ { r11s[24:0], r11s[31:25] };\nassign r12s = c15d + c14d;\nassign r12 = c12d ^ { r12s[24:0], r12s[31:25] };\n\nassign r02s = r01 + c00d;\nassign r02 = c02d ^ { r02s[22:0], r02s[31:23] };\nassign r07s = r06 + c05d;\nassign r07 = c07d ^ { r07s[22:0], r07s[31:23] };\nassign r08s = r11 + c10d;\nassign r08 = c08d ^ { r08s[22:0], r08s[31:23] };\nassign r13s = r12 + c15d;\nassign r13 = c13d ^ { r13s[22:0], r13s[31:23] };\n\nassign r03s = r02 + r01;\nassign r03 = c03d ^ { r03s[18:0], r03s[31:19] };\nassign r04s = r07 + r06;\nassign r04 = c04d ^ { r04s[18:0], r04s[31:19] };\nassign r09s = r08 + r11;\nassign r09 = c09d ^ { r09s[18:0], r09s[31:19] };\nassign r14s = r13 + r12;\nassign r14 = c14d ^ { r14s[18:0], r14s[31:19] };\n\nassign r00s = r03 + r02;\nassign r00 = c00d ^ { r00s[13:0], r00s[31:14] };\nassign r05s = r04 + r07;\nassign r05 = c05d ^ { r05s[13:0], r05s[31:14] };\nassign r10s = r09 + r08;\nassign r10 = c10d ^ { r10s[13:0], r10s[31:14] };\nassign r15s = r14 + r13;\nassign r15 = c15d ^ { r15s[13:0], r15s[31:14] };\n\nwire [511:0]xo;\t\t\t// Rename row results\nassign xo = { r15, r14, r13, r12, r11, r10, r09, r08, r07, r06, r05, r04, r03, r02, r01, r00 };\n\nassign Xaddr = xo[9:0];\t// Unregistered output\n\nalways @ (posedge clk)\nbegin\n\tc00d <= c00;\n\tc01d <= c01;\n\tc02d <= c02;\n\tc03d <= c03;\n\tc04d <= c04;\n\tc05d <= c05;\n\tc06d <= c06;\n\tc07d <= c07;\n\tc08d <= c08;\n\tc09d <= c09;\n\tc10d <= c10;\n\tc11d <= c11;\n\tc12d <= c12;\n\tc13d <= c13;\n\tc14d <= c14;\n\tc15d <= c15;\n\tout <= xo;\t\t// Registered output\nend\n\nendmodule\n"
  },
  {
    "path": "experimental/LX150-SLOWSIXTEEN-A/salsaengine.v",
    "content": "/* salsaengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n// NB HALFRAM no longer applies, configure via parameters ADDRBITS, THREADS\n\n// Bracket this config option in SIM so we don't accidentally leave it set in a live build\n`ifdef SIM\n//`define ONETHREAD\t// Start one thread only (for SIMULATION less confusing and faster startup)\n`endif\n\n`timescale 1ns/1ps\n\nmodule salsaengine (hash_clk, reset, din, dout, shift, start, busy, result );\n\n\n\tinput hash_clk;\n\tinput reset;\t// NB pbkdf_clk domain (need a long reset (at least THREADS+4) to initialize correctly, this is done in pbkdfengine\n\tinput shift;\n\tinput start;\t// NB pbkdf_clk domain\n\toutput busy;\n\toutput reg result = 1'b0;\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] din;\n\toutput [SBITS-1:0] dout;\n\n\t// Configure ADDRBITS to allocate RAM for core (automatically sets LOOKAHEAD_GAP)\n\t// NB do not use ADDRBITS > 13 for THREADS=8 or ADDRBITS > 14 for THREADS=16 as this is more than\n\t// a full scratchpad and the calculation for INT_BITS will be invalid.\n\n\t// These settings are now overriden in ltcminer_icarus.v determined by LOCAL_MINERS ...\n\t// These values are for THREADS=8, scratchpad sizes are halved for THREADS=16\n\t// parameter ADDRBITS = 14;\t// 16MBit RAM allocated to core, full scratchpad for THREADS=16(will not fit LX150)\n\t// parameter ADDRBITS = 13;\t//  8MBit RAM allocated to core, full scratchpad (will not fit LX150)\n\tparameter ADDRBITS = 12;\t//  4MBit RAM allocated to core, half scratchpad\n\t// parameter ADDRBITS = 11;\t//  2MBit RAM allocated to core, quarter scratchpad\n\t// parameter ADDRBITS = 10;\t//  1MBit RAM allocated to core, eighth scratchpad\n\n\t// Do not change THREADS - this must match the salsa pipeline (8 or 16 cycle latency for 8 or 16 threads)\n\tparameter THREADS = 16;\t\t// NB Phase has THREADS+1 cycles\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n\tparameter THREADS_BITS = clog2(THREADS);\n\t\n\treg [THREADS_BITS:0]phase = 0;\n\treg [THREADS_BITS:0]phase_d = THREADS;\n\treg reset_d=0, fsmreset=0, start_d=0, fsmstart=0;\n\n\talways @ (posedge hash_clk)\t\t// Phase control and sync\n\tbegin\n\t\tphase <= (phase == THREADS) ? 0 : phase + 1;\n\t\tphase_d <= phase;\n\t\treset_d <= reset;\t\t\t// Synchronise to hash_clk domain\n\t\tfsmreset <= reset_d;\n\t\tstart_d <= start;\n\t\tfsmstart <= start_d;\n\tend\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\tparameter XSmix = 0, XSload = 1, XSram = 2;\t// One-hot since these map directly to mux contrls\n\n\treg [1:0] XCtl = XSmix;\n\n\tparameter R_IDLE=0, R_START=1, R_LOAD=2, R_WRITE=3, R_MIX=4, R_INT=5, R_WAIT=6;\n\treg [2:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs\n\treg addrwriteMix = 1'b0;\n\treg addrreadInit = 1'b0;\n\treg addrreadSave = 1'b0;\n\treg xoren = 1'b0;\n\n\t// NB This caclulation does NOT work for ADDRBITS>13 with THREADS=8 or ADDRBITS>14 with THREADS=16\n\tparameter INT_BITS = THREADS_BITS - ADDRBITS + 10;\t// Max intcycle value is 15 for THREADS=16 and ADDRBITS=10, needing 5 bits\n\t// Where INT_BITS==0 we have a full scratchpad and intcycles is not used (though a 1 bit reg[0:0] is still allocated)\n\tparameter INT_BITX = (INT_BITS > 0) ? INT_BITS : INT_BITS+1;\t// Workaround for compilation errors in unused code branches\n\n\treg [INT_BITS:0] intcycles = 0;\t\t\t\t\t\t// Number of interpolation cycles required\n\n\twire [511:0] Xmix;\n\treg [511:0] X0;\n\treg [511:0] X1;\n\twire [511:0] X0in;\n\twire [511:0] X1in;\n\twire [511:0] X0out;\n\treg [1023:0] salsaShiftReg;\n\treg [31:0] nonce_sr;\t\t\t// In series with salsaShiftReg\n\tassign dout = salsaShiftReg[1023:1024-SBITS];\n\n\t// sstate is implemented in ram (alternatively could use a rotating shift register)\n\treg [INT_BITS+28:0] sstate [THREADS-1:0];\t\t// NB initialized via a long reset (see pbkdfengine)\n\t// List components of sstate here for ease of maintenance ...\n\twire [2:0] mstate_in;\n\twire [10:0] cycle_in;\n\twire [9:0] writeaddr_in;\n\twire doneROM_in;\n\twire addrwriteMix_in;\n\twire addrreadInit_in;\n\twire addrreadSave_in;\n\twire [INT_BITS:0] intcycles_in;\n\n\twire [9:0] writeaddr_next = writeaddr_in + 10'd1;\n\n\treg [31:0] snonce [THREADS-1:0];\t\t\t\t\t// Nonce store. Note bidirectional loading below, this will either implement\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// as registers or dual-port ram, so do NOT integrate with sstate.\n\t\n\t// NB There is no busy_in or result_in as these flags are NOT saved on a per-thread basis\n\n\t// Convert salsaShiftReg to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = salsaShiftReg[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\tend\n\tendgenerate\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of RAM size\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\twire [9:0] Xaddr;\n\twire [ADDRBITS-1:0]rd_addr;\n\twire [ADDRBITS-1:0]wr_addr1;\n\twire [ADDRBITS-1:0]wr_addr2;\n\twire [ADDRBITS-1:0]wr_addr3;\n\twire [ADDRBITS-1:0]wr_addr4;\n\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\t(* S = \"TRUE\" *) reg ram_wren = 1'b0;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\t// Top ram address is reserved for X0Save/X1save, so adjust\n\t\n\twire [15:0] memtop = 16'hfffe;\t// One less than the top memory location (per THREAD bank)\n\t\n\twire [9-INT_BITS:0] adj_addr;\n\n\tif (INT_BITS > 0)\n\t\tassign adj_addr = (Xaddr[9:INT_BITS] == memtop[9:INT_BITS]) ?\n\t\t\t\t\t\t\tmemtop[9-INT_BITS:0] : Xaddr[9:INT_BITS];\n\telse\n\t\tassign adj_addr = Xaddr;\n\t\n\twire [THREADS_BITS-1:0] phase_addr;\t\t\t\t\t// Prefix for read address\n\tassign phase_addr = phase[THREADS_BITS-1:0];\n\treg [THREADS_BITS-1:0] phase_addr_d = 0;\t\t\t// Prefix for write address\n\n\tassign rd_addr = { phase_addr,\n\t\t\t\t\t\t(addrreadSave_in | addrreadInit_in) ?\n\t\t\t\t\t\t\t(addrreadInit_in ? {ADDRBITS-THREADS_BITS{1'b0}} : memtop[ADDRBITS-THREADS_BITS:1])\n\t\t\t\t\t\t:\n\t\t\t\t\t\t\tadj_addr };\n\t\t\n\twire [9:0] writeaddr_adj = addrwriteMix ? memtop[10:1] : writeaddr;\n\t\n\tassign wr_addr1 = { phase_addr_d, writeaddr_adj[9:INT_BITS] };\n\tassign wr_addr2 = { phase_addr_d, writeaddr_adj[9:INT_BITS] };\n\tassign wr_addr3 = { phase_addr_d, writeaddr_adj[9:INT_BITS] };\n\tassign wr_addr4 = { phase_addr_d, writeaddr_adj[9:INT_BITS] };\n\n\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_1 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_2 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_3 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_4 = 0;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr1 = rd_addr | rd_addr_z_1;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr2 = rd_addr | rd_addr_z_2;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr3 = rd_addr | rd_addr_z_3;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr4 = rd_addr | rd_addr_z_4;\n\t\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (rd_addr1, wr_addr1, ram_clk, ram1_din, ram_wren, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (rd_addr2, wr_addr2, ram_clk, ram2_din, ram_wren, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (rd_addr3, wr_addr3, ram_clk, ram3_din, ram_wren, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (rd_addr4, wr_addr4, ram_clk, ram4_din, ram_wren, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\n\t// Two ram data sources, the initial X value and the salsa output\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = XCtl[0] ? X : { Xmix, X0out};\t// Registered input\n\t\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, X0, X1, Xmix, X0out, Xaddr);\n\n\t// Main multiplexer\n\twire [511:0] Zbits;\n\tassign Zbits = {512{xoren}};\t\t// xoren enables xor from ram (else we load from ram)\n\t\n\t// XSMix is now the default and the initial load is now done via RAM to simplify the pipeline\n\tassign X0in =  XCtl[1] ? (X0out & Zbits) ^ ramout[511:0]    : X0out;\n\tassign X1in =  XCtl[1] ? (Xmix  & Zbits) ^ ramout[1023:512] : Xmix;\n\n\t// Salsa FSM - TODO may want to move this into a separate function (for floorplanning), see hashvariant-C\n\n\t// Hold separate state for each thread (a bit of a kludge to avoid rewriting FSM from scratch)\n\t// NB must ensure shift and result do NOT overlap by carefully controlling timing of start signal\n\t// NB Phase has THREADS+1 cycles, but we do not save the state for (phase==THREADS) as it is never active\n\n\tassign { mstate_in, writeaddr_in, cycle_in, doneROM_in, addrwriteMix_in, addrreadInit_in, addrreadSave_in, intcycles_in} =\n\t\t\t\t(phase == THREADS ) ? 0 : sstate[phase];\t\n\t\n\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\n\treg busy_flag = 1'b0;\n\t\n`ifdef ONETHREAD\n\t// TEST CONTROLLER ... just allow a single thread to run (busy is currently a common flag)\n\t// NB the thread automatically restarts after it completes, so its a slight misnomer to say it starts once.\n\treg start_once = 1'b0;\n\twire start_flag;\n\tassign start_flag = fsmstart & ~start_once;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine\n`else\n\t// NB start_flag only has effect when a thread is at R_IDLE, ie after reset, normally a thread will automatically\n\t// restart on completion. We need to spread the R_IDLE starts evenly to ensure proper ooperation. NB the pbkdf\n\t// engine requires busy and result, but this  looks alter itself in the salsa FSM, even though these are global\n\t// flags. Reset periodically (on loadnonce in pbkdfengine) to ensure it stays in sync.\n\treg [15:0] start_count = 0;\n\n\t// For THREADS=8, lookup_gap=2 salsa takes on average 9*(1024+(1024*1.5)) = 23040 clocks, generically 9*1024*(lookup_gap/2+1.5)\n\t// For THREADS=16, use 17*1024*(lookup_gap/2+1.5), where lookupgap is double that for THREADS=8\n\t// This is OK, but only does ADDRBITS=10,11,12 ...\n\t// parameter START_INTERVAL = (THREADS==16) ?\t((ADDRBITS==12) ? 60928 : (ADDRBITS==11) ? 95744 : 165376) / THREADS :\t// 16 threads\n\t//\t\t\t\t\t\t\t\t\t\t\t\t((ADDRBITS==12) ? 23040 : (ADDRBITS==11) ? 36864 :  50688) / THREADS ;\t//  8 threads\n\t// This seems to work OK generically (TODO check full scratchpad) ...\n\tparameter START_INTERVAL = (THREADS+1) * 1024 * ((1 << (15-ADDRBITS)) * THREADS / 32 + 3) / THREADS / 2;\n\n\treg start_flag = 1'b0;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine - this will toggle on transtion through R_START\n`endif\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tX0 <= X0in;\n\t\tX1 <= X1in;\n\t\t\n\t\tif (phase_d != THREADS)\n\t\t\tsstate[phase_d] <= fsmreset ? 0 : { mstate, writeaddr, cycle, doneROM, addrwriteMix, addrreadInit, addrreadSave, intcycles };\n\n\t\tmstate <= mstate_in;\t\t// Set defaults (overridden below as necessary)\n\t\twriteaddr <= writeaddr_in;\n\t\tcycle <= cycle_in;\n\t\tintcycles <= intcycles_in;\n\t\tdoneROM <= doneROM_in;\n\t\taddrwriteMix <= addrwriteMix_in;\n\t\taddrreadInit <= addrreadInit_in;\n\t\taddrreadSave <= addrreadSave_in;\t\t// Overwritten below, but addrreadSave_in is used above\n\t\t\n\t\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\trd_addr_z_1 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_2 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_3 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_4 <= {ADDRBITS{fsmreset}};\n\n\t\tphase_addr_d <= phase[THREADS_BITS-1:0];\n\t\t\n\t\tXCtl <= XSmix;\t\t\t\t// Default states\n\t\taddrreadInit <= 1'b0;\t\t// NB addrreadInit_in is the active control so this DOES need to be in sstate\n\t\taddrreadSave <= 1'b0;\t\t// Ditto\n\t\tram_wren <= 1'b0;\n\t\txoren <= 1'b1;\n\t\t\n\t\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\t\t`ifdef ONETHREAD\n\t\tif (fsmstart && phase!=THREADS)\n\t\t\tstart_once <= 1'b1;\n\t\tif (fsmreset)\n\t\t\tstart_once <= 1'b0;\n\t\t`else\n\t\tstart_count <= start_count + 1;\n\t\t// start_flag <= 1'b0;\t\t\t// Done below when we transition out of R_IDLE\n\t\tif (fsmreset || start_count == START_INTERVAL)\n\t\tbegin\n\t\t\tstart_count <= 0;\n\t\t\tif (~fsmreset && fsmstart)\n\t\t\t\tstart_flag <= 1'b1;\n\t\tend\n\t\t`endif\n\t\t\n\t\t// Could use explicit mux for this ...\n\t\tif (shift)\n\t\tbegin\n\t\t\tsalsaShiftReg <= { salsaShiftReg[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], din};\n\t\tend\n\t\telse\n\t\tif (XCtl[0] && phase_d != THREADS)\t\t// Set at end of previous hash - this is executed regardless of phase\t\t\n\t\tbegin\n\t\t\tsalsaShiftReg <= ramout;\t\t\t// Simultaneously with XSload\n\t\t\tnonce_sr <= snonce[phase_d];\t\t// NB bidirectional load\n\t\t\tsnonce[phase_d] <= nonce_sr;\n\t\tend\n\t\t\n\t\tif (fsmreset == 1'b1)\n\t\tbegin\n\t\t\tmstate <= R_IDLE;\t\t// This will propagate to all sstate slots as we hold reset for 10 cycles\n\t\t\tbusy_flag <= 1'b0;\n\t\t\tresult <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate_in)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\t// R_IDLE only applies after reset. Normally each thread will reenter at S_START and\n\t\t\t\t\t// assumes that input data is waiting (this relies on the threads being started evenly,\n\t\t\t\t\t// hence the interface FSM at the top of this file)\n\t\t\t\t\tif (phase!=THREADS && start_flag)\t// Ensure (phase==THREADS) slot is never active\n\t\t\t\t\tbegin\n\t\t\t\t\t\t`ifndef ONETHREAD\n\t\t\t\t\t\t\tstart_flag <= 1'b0;\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t\t// Toggle the busy flag low to ack pbkdfengine (its usually already set\n\t\t\t\t\t\t\t\t\t\t\t\t// since other threads are running)\n\t\t\t\t\t\tmstate <= R_START;\n\n\t\t\t\t\t\t// We cycle the initial data through the RAM to simplify the data path (costs 17 clocks)\n\t\t\t\t\t\t// Setup to write initial data to ram (on next clock)\n\t\t\t\t\t\twriteaddr <= 0;\n\t\t\t\t\t\taddrwriteMix <= 1'b0;\n\t\t\t\t\t\tram_wren <= 1'b1;\n\n\t\t\t\t\t\t// Setup to read initial data back from ram (17 clocks later)\n\t\t\t\t\t\tXCtl <= XSload;\n\t\t\t\t\t\taddrreadInit <= 1'b1;\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tR_START: begin\t\t\t\t\t// Reentry point after thread completion. ASSUMES new data is ready.\n\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\txoren <= 1'b0;\n\t\t\t\t\tcycle <= 0;\n\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\tbusy_flag <= 1'b1;\n\t\t\t\t\tresult <= 1'b0;\n\t\t\t\t\tmstate <= R_LOAD;\n\t\t\t\tend\n\n\t\t\t\tR_LOAD: begin\t\t\t\t\t// Now loading initial data via RAM to simplify data path (costs 17 clocks)\n\t\t\t\t\twriteaddr <= writeaddr_next;\n\t\t\t\t\tif (INT_BITS == 0)\n\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Full scratchpad needs to write to addr=001 next cycle\n\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\tend\n\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\twriteaddr <= writeaddr_next;\n\n\t\t\t\t\tif (writeaddr_in==1022)\n\t\t\t\t\t\tdoneROM <= 1'b1;\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\t\n\t\t\t\t\tif (doneROM_in)\n\t\t\t\t\tbegin\n\t\t\t\t\t\taddrwriteMix <= 1'b1;\t// Remains set for duration of R_MIX\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Load from ram next cycle (xor'd with XMix)\n\t\t\t\t\t\t// Need this to cover the case of the initial read being interpolated\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_MIX\n\t\t\t\t\t\tif (INT_BITS > 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { 1'b0, Xaddr[INT_BITX-1:0] };\t// Interpolated addresses\n\t\t\t\t\t\t\tif ( Xaddr[9:INT_BITX] ==  memtop[10-INT_BITX:1] )\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { 1'b1, Xaddr[INT_BITX-1:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:INT_BITX] == memtop[10-INT_BITX:1]) || |Xaddr[INT_BITX-1:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 1'b0;\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[INT_BITX-1:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:INT_BITX] ==  memtop[10-INT_BITX:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrreadSave <= 1'b1;\t\t// Preset to read saved data (17 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tram_wren <=\t(INT_BITS > 0) ? ~|writeaddr_next[INT_BITX-1:0] : 1'b1;\t\t\t\t\t\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\tcycle <= cycle_in + 11'd1;\n\t\t\t\t\tif (cycle_in==1023)\n\t\t\t\t\tbegin\n\t\t\t\t\t\t// We now ALWAYS write result to ram, thus simplifying the data path at the cost of 17 clock cycles\n\t\t\t\t\t\tmstate <= R_WAIT;\n\t\t\t\t\t\taddrreadSave <= 1'b1;\t\t// Preset to read saved data (17 clocks later)\n\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Save result\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle (xor'd with XMix)\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_WRITE\n\t\t\t\t\t\tif (INT_BITS > 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { 1'b0, Xaddr[INT_BITX-1:0] };\t\t\t// Interpolated addresses\n\t\t\t\t\t\t\tif ( Xaddr[9:INT_BITX] ==  memtop[10-INT_BITX:1] )\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { 1'b1, Xaddr[INT_BITX-1:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:INT_BITX] == memtop[10-INT_BITX:1]) || |Xaddr[INT_BITX-1:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 1'b0;\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[INT_BITX-1:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:INT_BITX] ==  memtop[10-INT_BITX:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrreadSave <= 1'b1;\t\t// Preset to read saved data (17 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tR_INT: begin\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\tintcycles <= intcycles_in - 1;\n\t\t\t\t\tif (intcycles_in==2)\n\t\t\t\t\t\taddrreadSave <= 1'b1;\t// Preset to read saved data (17 clocks later)\n\t\t\t\t\tif (intcycles_in==1)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Setup to XOR from saved X0/X1 in ram at next cycle\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\tend\n\t\t\t\t\t// Else mstate remains at R_INT so we continue interpolating\n\t\t\t\tend\n\n\t\t\t\tR_WAIT: begin\n\t\t\t\t\t\tif (fsmstart)\t\t\t// Check data input is ready\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\tbusy_flag <= 1'b0;\t\t// Will hold at 0 for 17 clocks until set at R_START\n\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\tmstate <= R_START;\t\t// Restart immediately\n\n\t\t\t\t\t\t\t// We cycle the initial data through the RAM to simplify the data path (costs 17 clocks)\n\t\t\t\t\t\t\t// Setup to write initial data to ram (on next clock)\n\t\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\t\taddrwriteMix <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t// Setup to read initial data back from ram (17 clocks later)\n\t\t\t\t\t\t\tXCtl <= XSload;\n\t\t\t\t\t\t\taddrreadInit <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\taddrreadSave <= 1'b1;\t\t// Preset to read saved data (17 clocks later)\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\t// if (mstate==R_MIX)\n\t//\t$display (\"phase %d cycle %d Xmix %08x\\n\", phase, cycle-1, Xmix[511:480]);\n`endif\n\tend\t// always @(posedge hash_clk)\nendmodule"
  },
  {
    "path": "experimental/LX150-SLOWSIXTEEN-A/test_icarus.v",
    "content": "// Testbench for ltcminer_icarus.v\n\n`timescale 1ns/1ps\n\n`ifdef SIM\t\t\t\t\t// Avoids wrong top selected if included in ISE/PlanAhead sources\nmodule test_ltcminer ();\n\n\treg clk = 1'b0;\n\treg [31:0] cycle = 32'd0;\n\n\tinitial begin\n\t\tclk = 0;\n\t\t\n\t\twhile(1)\n\t\tbegin\n\t\t\t#5 clk = 1; #5 clk = 0;\n\t\tend\n\tend\n\n\talways @ (posedge clk)\n\tbegin\n\t\tcycle <= cycle + 32'd1;\n\tend\n\t\n\t// Running with default zero's for the data1..3 regs.\n\t// tx_hash=553a4b69b43913a61b42013ce210f713eaa7332e48cda1bdf3b93b10161d0876 at 187,990 nS and\n\t// final_hash (if SIM is defined) at 188,000 nS with golden_nonce_match flag NOT set since it is\n\t// not a diff=32 share. To test golden_nonce, just tweak the target eg 31'hffffffff will match everything\n\t\n\t// With serial input(at comm_clk_frequency=1_000_000), we get rx_done at t=70,220nS, however there is already a\n\t// PBKDF2_SHA256_80_128 loaded in Xbuf (for nonce=00000001). The first final_hash at 188,000 nS is corrupted as\n\t// the input data has changed from all 0's. The Xbuf starts salsa rom at t=188,000 but the nonce is incorrectly\n\t// taken from the newly loaded data so once salsa in complete it also generates a corrupt final_hash at ~362,000 nS.\n\t// Nonce is incremented then the newly loaded data starts PBKDF2_SHA256_80_128, so we must supply a nonce 1 less\n\t// than the expected golden_nonce. The correct PBKDF2_SHA256_80_128 is ready at ~ 197,000 nS. We get final_hash for\n\t// the corrupted work at ~362,000 nS then our required golden_nonce is at 536,180 nS.\n\t// This is only really a problem for simulation. With live hashing we just lose 2 nonces every time getwork is\n\t// loaded, which isn't a big deal.\n\t\t\n\twire RxD;\n\twire TxD;\n\twire extminer_rxd = 0;\n\twire extminer_txd;\n\twire [3:0] dip = 0;\n\twire [3:0] led;\n\twire TMP_SCL=1, TMP_SDA=1, TMP_ALERT=1;\n\t\n\tparameter comm_clk_frequency = 1_000_000;\t// Speeds up serial loading enormously rx_done is at t=70,220nS\n\tparameter baud_rate = 115_200;\n\t\n\tltcminer_icarus #(.comm_clk_frequency(comm_clk_frequency)) uut\n\t\t(clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n\t// Send serial data - 84 bytes, matches on nonce 318f (included in data)\n\t// NB starting nonce is 381e NOT 381f (see note above)\n\t\n\t// NORMAL...\n\t// reg [671:0] data = 672'h000007ff0000318e7e71441b141fe951b2b0c7dfc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af75575618e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\n\t// DYNPLL...\n\treg [671:0] data = 672'h55aa07ff0000318e7e71441b141fe951b2b0c7dfc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af75575618e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\t\n\treg\t\t\tserial_send = 0;\n\twire\t\tserial_busy;\n\treg [31:0]\tdata_32 = 0;\n\treg [31:0]\tstart_cycle = 0;\n\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(baud_rate)) sertx (.clk(clk), .TxD(RxD), .send(serial_send), .busy(serial_busy), .word(data_32));\n\n\t// TUNE this according to comm_clk_frequency so we send a single getwork (else it gets overwritten with 0's)\n\t// parameter stop_cycle = 7020;\t\t// For comm_clk_frequency=1_000_000\n\tparameter stop_cycle = 0;\t\t\t// Use this to DISABLE sending data\n\talways @ (posedge clk)\n\tbegin\n\t\tserial_send <= 0;\t\t\t\t// Default\n\t\t// Send data every time tx goes idle (NB the !serial_send is to prevent serial_send\n\t\t// going high for two cycles since serial_busy arrives one cycle after serial_send)\n\t\tif (cycle > 5 && cycle < stop_cycle && !serial_busy && !serial_send)\n\t\tbegin\n\t\t\tserial_send <= 1;\n\t\t\tdata_32 <= data[671:640];\n\t\t\tdata <= { data[639:0], 32'd0 };\n\t\t\tstart_cycle <= cycle;\t\t// Remember each start cycle (makes debugging easier)\n\t\tend\n\tend\n\nendmodule\n`endif"
  },
  {
    "path": "experimental/LX150-SLOWSIXTEEN-A/xilinx_dpram.v",
    "content": "// xilinx_ram.v - inferring the ram seems to work fine\n\nmodule ram # ( parameter ADDRBITS=10 ) (\n\traddr,\n\twaddr,\n\tclock,\n\tdata,\n\twren,\n\tq);\n\n\tinput\t[ADDRBITS-1:0]  raddr;\n\tinput\t[ADDRBITS-1:0]  waddr;\n\tinput\t  clock;\n\tinput\t[255:0]  data;\n\tinput\t  wren;\n\toutput\t[255:0]  q;\n\n\t//synthesis attribute ram_style of store is block\n\treg [255:0] store [(2 << (ADDRBITS-1))-1:0];\n\treg[ADDRBITS-1:0] raddr_reg;\n\t\n\talways @ (posedge clock)\n\tbegin\n\t\traddr_reg <= raddr;\n\t\tif (wren)\n\t\t\tstore[waddr] <= data;\n\tend\n\t\n\tassign q = store[raddr_reg];\n\t\t\t\nendmodule"
  },
  {
    "path": "experimental/LX150-SLOWSIXTEEN-A/xilinx_dyn_pll.v",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 1995-2011 Xilinx, Inc.  All rights reserved.\n////////////////////////////////////////////////////////////////////////////////\n//   ____  ____ \n//  /   /\\/   / \n// /___/  \\  /    Vendor: Xilinx \n// \\   \\   \\/     Version : 13.1\n//  \\   \\         Application : xaw2verilog\n//  /   /         Filename : main_pll.v\n// /___/   /\\     Timestamp : 06/03/2011 01:58:13\n// \\   \\  /  \\ \n//  \\___\\/\\___\\ \n//\n//Command: xaw2verilog -st /home/teknohog/dcm2/ipcore_dir/./main_pll.xaw /home/teknohog/dcm2/ipcore_dir/./main_pll\n//Design Name: main_pll\n//Device: xc3s500e-4fg320\n//\n// Module main_pll\n// Generated by Xilinx Architecture Wizard\n// Written for synthesis tool: XST\n\n`timescale 1ns / 1ps\n\nmodule dyn_pll # (parameter SPEED_MHZ = 25 )\n\t(CLKIN_IN, \n\tCLKFX1_OUT, \n\tCLKFX2_OUT, \n\tCLKDV_OUT,\n\tDCM_SP_LOCKED_OUT,\n\tdcm_progclk,\n\tdcm_progdata,\n\tdcm_progen,\n\tdcm_reset,\n\tdcm_progdone,\n\tdcm_locked,\n\tdcm_status);\n\t\n\tinput CLKIN_IN;\n\twire CLKIN_IBUFG_OUT;\n\twire CLK0_OUT;\n\toutput CLKFX1_OUT;\n\toutput CLKFX2_OUT;\n\toutput CLKDV_OUT;\n\toutput DCM_SP_LOCKED_OUT;\n\n\tinput dcm_progclk;\n\tinput dcm_progdata;\n\tinput dcm_progen;\n\tinput dcm_reset;\n\toutput dcm_progdone;\n\toutput dcm_locked;\n\toutput [2:1] dcm_status;\n\t\n\twire CLKFB_IN;\n\twire CLKIN_IBUFG;\n\twire CLK0_BUF;\n\twire CLKFX1_BUF;\n\twire CLKFX2_BUF;\n\twire CLKDV_BUF;\n\twire GND_BIT;\n\twire dcm_progclk_buf;\n\n\tassign GND_BIT = 0;\n\tassign CLKIN_IBUFG_OUT = CLKIN_IBUFG;\n\tassign CLK0_OUT = CLKFB_IN;\n\t\n\tIBUFG  CLKIN_IBUFG_INST (.I(CLKIN_IN), \n\t\t.O(CLKIN_IBUFG));\n\tBUFG  CLK0_BUFG_INST (.I(CLK0_BUF), \n\t\t.O(CLKFB_IN));\n\tBUFG  CLKFX1_BUFG_INST (.I(CLKFX1_BUF), \n\t\t.O(CLKFX1_OUT));\n\tBUFG  CLKFX2_BUFG_INST (.I(CLKFX2_BUF), \n\t\t.O(CLKFX2_OUT));\n\tBUFG  CLKDV_BUFG_INST (.I(CLKDV_BUF), \n\t\t.O(CLKDV_OUT));\n\tBUFG  DCMPROGCLK_BUFG_INST (.I(dcm_progclk), \n\t\t.O(dcm_progclk_buf));\n\n\t// 100 MHZ osc gives fixed 50MHz CLKFX1, 12.5MHZ CLKDV\n\tDCM_SP #( .CLK_FEEDBACK(\"1X\"), .CLKDV_DIVIDE(8.0), .CLKFX_DIVIDE(8),\n\t\t.CLKFX_MULTIPLY(4), .CLKIN_DIVIDE_BY_2(\"FALSE\"), \n\t\t.CLKIN_PERIOD(10.000), .CLKOUT_PHASE_SHIFT(\"NONE\"), \n\t\t.DESKEW_ADJUST(\"SYSTEM_SYNCHRONOUS\"), .DFS_FREQUENCY_MODE(\"LOW\"), \n\t\t.DLL_FREQUENCY_MODE(\"LOW\"), .DUTY_CYCLE_CORRECTION(\"TRUE\"), \n\t\t.FACTORY_JF(16'hC080), .PHASE_SHIFT(0), .STARTUP_WAIT(\"FALSE\") ) \n\t\tDCM_SP_INST (.CLKFB(CLKFB_IN), \n\t\t.CLKIN(CLKIN_IBUFG), \n\t\t.DSSEN(GND_BIT), \n\t\t.PSCLK(GND_BIT), \n\t\t.PSEN(GND_BIT), \n\t\t.PSINCDEC(GND_BIT), \n\t\t.RST(GND_BIT), \n\t\t.CLKDV(CLKDV_BUF), \n\t\t.CLKFX(CLKFX1_BUF), \n\t\t.CLKFX180(), \n\t\t.CLK0(CLK0_BUF), \n\t\t.CLK2X(), \n\t\t.CLK2X180(), \n\t\t.CLK90(), \n\t\t.CLK180(), \n\t\t.CLK270(), \n\t\t.LOCKED(DCM_SP_LOCKED_OUT), \n\t\t.PSDONE(), \n\t\t.STATUS());\n\n\tDCM_CLKGEN #(\n\t\t.CLKFX_DIVIDE(100),\t\t\t// 100Mhz osc so gives steps of 1MHz\n\t\t.CLKFX_MULTIPLY(SPEED_MHZ),\n\t\t.CLKFXDV_DIVIDE(2),\t\t\t// Unused\n\t\t.CLKIN_PERIOD(10.0),\n\t\t.CLKFX_MD_MAX(0.000),\n\t\t.SPREAD_SPECTRUM(\"NONE\"),\n\t\t.STARTUP_WAIT(\"FALSE\")\n\t\t) \n\t\tDCM_CLKGEN_INST (\n\t\t.CLKIN(CLKIN_IBUFG),\n\t\t.CLKFX(CLKFX2_BUF),\n\t\t.FREEZEDCM(1'b0),\n\t\t.PROGCLK(dcm_progclk_buf),\n\t\t.PROGDATA(dcm_progdata),\n\t\t.PROGEN(dcm_progen),\n\t\t.PROGDONE(dcm_progdone),\n\t\t.LOCKED(dcm_locked),\n\t\t.STATUS(dcm_status),\n\t\t.RST(dcm_reset)\n\t\t);\n\nendmodule\n"
  },
  {
    "path": "experimental/LX150-SPLIT/README.txt",
    "content": "LX150_SPLIT\n\nSplits the pbkdf and salsa engines into separates modules and implements a serial\nshift register protocol for communication to reduce routing of wide buses.\n\nUses the original salsa.v.\n\nFurther work is needed to allow multiple salsa engines to be served from a single pbkdf\nengine. However this is an interim design leading on to the pipelined LX150_EIGHT (and\nperhaps even LX150_SIXTYFOUR) which will require deep interpolation and likely only a\nsingle core will fit onto a LX150, so its not a priority right now."
  },
  {
    "path": "experimental/LX150-SPLIT/ltcminer_icarus.ucf",
    "content": "# Based on https://github.com/ngzhang/Icarus/blob/master/FPGA_project/Src/fpgaminer_top.ucf\nNET \"osc_clk\" LOC = J1;\n\n# serial port receive & transmit\nNET \"RxD\" LOC = D1;\nNET \"TxD\" LOC = B1;\n\n# TTL level serial port: ja3 = rxd, ja2 = txd\nNET \"extminer_txd[0]\" LOC = D22;\nNET \"extminer_rxd[0]\" LOC = B22;\n\n# Button 0\n//NET \"reset\" LOC = \"A4\";\n\nNET \"led[0]\" LOC = A18;\nNET \"led[1]\" LOC = B18;\nNET \"led[2]\" LOC = A17;\nNET \"led[3]\" LOC = A16;\n\nNET \"dip[0]\" LOC = A4;\nNET \"dip[1]\" LOC = D6;\nNET \"dip[2]\" LOC = C6;\nNET \"dip[3]\" LOC = C8;\n\nNET \"TMP_SCL\" LOC = C1;\nNET \"TMP_SDA\" LOC = E1;\nNET \"TMP_ALERT\" LOC = C3;\n\nNET \"hash_clk\" TNM_NET = \"hash_clk\";\nNET \"uart_clk\" TNM_NET = \"uart_clk\";\n\n# 25MHz hash_clk\nTIMESPEC TS_hash_clk = PERIOD \"hash_clk\" 40 ns HIGH 50 % INPUT_JITTER 7 ps;\n# 12.5MHz uart_clk\nTIMESPEC TS_uart_clk = PERIOD \"uart_clk\" 80 ns HIGH 50 %;\n\nNET \"TMP_ALERT\" IOSTANDARD = LVCMOS33;\nNET \"TMP_ALERT\" PULLUP;\nNET \"TMP_SDA\" IOSTANDARD = LVCMOS33;\nNET \"TMP_SDA\" PULLUP;\nNET \"TMP_SCL\" PULLUP;\nNET \"TMP_SCL\" IOSTANDARD = LVCMOS33;\nNET \"dip[3]\" IOSTANDARD = LVCMOS33;\nNET \"led[3]\" IOSTANDARD = LVCMOS33;\nNET \"dip[2]\" IOSTANDARD = LVCMOS33;\nNET \"dip[1]\" IOSTANDARD = LVCMOS33;\nNET \"TxD\" IOSTANDARD = LVCMOS33;\nNET \"osc_clk\" IOSTANDARD = LVCMOS33;\nNET \"led[2]\" IOSTANDARD = LVCMOS33;\nNET \"extminer_rxd[0]\" IOSTANDARD = LVCMOS33;\nNET \"dip[0]\" IOSTANDARD = LVCMOS33;\nNET \"RxD\" IOSTANDARD = LVCMOS33;\nNET \"extminer_txd[0]\" IOSTANDARD = LVCMOS33;\nNET \"led[0]\" IOSTANDARD = LVCMOS33;\nNET \"led[1]\" IOSTANDARD = LVCMOS33;\n"
  },
  {
    "path": "experimental/LX150-SPLIT/ltcminer_icarus.v",
    "content": "/* ltcminer_icarus.v copyright kramble 2013\n * Based on https://github.com/teknohog/Open-Source-FPGA-Bitcoin-Miner/tree/master/projects/Xilinx_cluster_cgminer\n * Hub code for a cluster of miners using async links\n * by teknohog\n */\n\n`include \"../../source/sha-256-functions.v\"\n`include \"../../source/sha256_transform.v\"\n`include \"../../source/salsa.v\"\n`include \"../../ICARUS-LX150/xilinx_ram.v\"\n`include \"../../ICARUS-LX150/xilinx_pll.v\"\n`include \"../../ICARUS-LX150/uart_receiver.v\"\n`include \"../../ICARUS-LX150/uart_transmitter.v\"\n`include \"../../ICARUS-LX150/serial.v\"\n`include \"../../ICARUS-LX150/serial_hub.v\"\n`include \"../../ICARUS-LX150/hub_core.v\"\n`include \"../../ICARUS-LX150/pwm_fade.v\"\n\nmodule ltcminer_icarus (osc_clk, RxD, TxD, led, extminer_rxd, extminer_txd, dip, TMP_SCL, TMP_SDA, TMP_ALERT);\n\n// NB SPEED_MHZ resolution is 5MHz steps to keep pll divide ratio sensible. Change the divider in xilinx_pll.v if you\n// want other steps (1MHz is not sensible as it requires divide 100 which is not in the allowed range 1..32 for DCM_SP)\n// TODO dynamic speed adjustment (possibly use top byte of target to set multiplier, this keeps serial interface compatible)\n`ifdef SPEED_MHZ\n\tparameter SPEED_MHZ = `SPEED_MHZ;\n`else\n\tparameter SPEED_MHZ = 25;\n`endif\n\n`ifdef SERIAL_CLK\n\tparameter comm_clk_frequency = `SERIAL_CLK;\n`else\n\tparameter comm_clk_frequency = 12_500_000;\t\t// 100MHz divide 8\n`endif\n\n`ifdef BAUD_RATE\n\tparameter BAUD_RATE = `BAUD_RATE;\n`else\n\tparameter BAUD_RATE = 115_200;\n`endif\n\n// kramble - since using separare clocks for uart and hasher, need clock crossing logic\n\tinput osc_clk;\n\twire hash_clk, uart_clk;\n\n`ifndef SIM\n\tmain_pll # (.SPEED_MHZ(SPEED_MHZ)) pll_blk (.CLKIN_IN(osc_clk), .CLKFX_OUT(hash_clk), .CLKDV_OUT(uart_clk));\n`else\n\tassign hash_clk = osc_clk;\n\tassign uart_clk = osc_clk;\n`endif\n   \n// kramble - nonce distribution is crude using top 4 bits of nonce so max LOCAL_MINERS = 8\n// teknohog's was more sophisticated, but requires modification of hashcore.v\n\n// Miners on the same FPGA with this hub\n`ifdef LOCAL_MINERS\n\tparameter LOCAL_MINERS = `LOCAL_MINERS;\n`else\n\tparameter LOCAL_MINERS = 1;\t\t\t\t\t// Only ONE core of LX150_FOUR will fit\n`endif\n\n// kramble - nonce distribution only works for a single external port \n`ifdef EXT_PORTS\n\tparameter EXT_PORTS = `EXT_PORTS;\n`else\n\tparameter EXT_PORTS = 1;\n`endif\n\n\tlocalparam SLAVES = LOCAL_MINERS + EXT_PORTS;\n\n\tinput TMP_SCL, TMP_SDA, TMP_ALERT;\t// Unused but set to PULLUP so as to avoid turning on the HOT LED\n\t\t\t\t\t\t\t\t\t\t// TODO implement I2C protocol to talk to temperature sensor chip (TMP101?)\n\t\t\t\t\t\t\t\t\t\t// and drive FAN speed control output.\n\n\tinput [3:0]dip;\n\twire reset, nonce_chip;\n\tassign reset = dip[0];\t\t\t// Not used\n\tassign nonce_chip = dip[1];\t\t// Distinguishes between the two Icarus FPGA's\n\n\t// Work distribution is simply copying to all miners, so no logic\n\t// needed there, simply copy the RxD.\n\tinput\tRxD;\n\toutput\tTxD;\n\n\t// Results from the input buffers (in serial_hub.v) of each slave\n\twire [SLAVES*32-1:0]\tslave_nonces;\n\twire [SLAVES-1:0]\t\tnew_nonces;\n\n\t// Using the same transmission code as individual miners from serial.v\n\twire\t\tserial_send;\n\twire\t\tserial_busy;\n\twire [31:0]\tgolden_nonce;\n\tserial_transmit #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) sertx (.clk(uart_clk), .TxD(TxD), .send(serial_send), .busy(serial_busy), .word(golden_nonce));\n\n\thub_core #(.SLAVES(SLAVES)) hc (.uart_clk(uart_clk), .new_nonces(new_nonces), .golden_nonce(golden_nonce), .serial_send(serial_send), .serial_busy(serial_busy), .slave_nonces(slave_nonces));\n\n\t// Common workdata input for local miners\n\twire [255:0]\tdata1, data2;\n\twire [127:0]\tdata3;\n\twire [31:0]\t\ttarget;\n\t// reg [31:0]\ttargetreg = 32'hffffffff;\t// TEST - matches ANYTHING\n\treg  [31:0]\t\ttargetreg = 32'h000007ff;\t// Start at sane value (overwritten by serial_receive)\n\twire\t\t\trx_done;\t\t// Signals hashcore to reset the nonce\n\t\t\t\t\t\t\t\t\t// NB in my implementation, it loads the nonce from data3 which should be fine as\n\t\t\t\t\t\t\t\t\t// this should be zero, but also supports testing using non-zero nonces.\n\n\t// Synchronise across clock domains from uart_clk to hash_clk\n\t// This probably looks amateurish (mea maxima culpa, novice verilogger at work), but should be OK\n\treg rx_done_toggle = 1'b0;\t\t// uart_clk domain\n\talways @ (posedge uart_clk)\n\t\trx_done_toggle <= rx_done_toggle ^ rx_done;\n\n\treg rx_done_toggle_d1 = 1'b0;\t// hash_clk domain\n\treg rx_done_toggle_d2 = 1'b0;\n\treg rx_done_toggle_d3 = 1'b0;\n\t\n\twire loadnonce;\n\tassign loadnonce = rx_done_toggle_d3 ^ rx_done_toggle_d2;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\trx_done_toggle_d1 <= rx_done_toggle;\n\t\trx_done_toggle_d2 <= rx_done_toggle_d1;\n\t\trx_done_toggle_d3 <= rx_done_toggle_d2;\n\t\tif (loadnonce)\n\t\t\ttargetreg <= target;\n\tend\n\t// End of clock domain sync\n\n\tserial_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) serrx (.clk(uart_clk), .RxD(RxD), .data1(data1),\n\t\t\t\t\t\t.data2(data2), .data3(data3), .target(target), .rx_done(rx_done));\n\n\t// Local miners now directly connected\n\tgenerate\n\t\tgenvar i;\n\t\tfor (i = 0; i < LOCAL_MINERS; i = i + 1)\n\t\tbegin: for_local_miners\n\t\t\twire [31:0] nonce_out;\t// Not used\n\t\t\twire [2:0] nonce_core = i;\n\t\t\twire gn_match;\n\t\t\t\n\t\t\twire salsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift;\n\n\t\t\t// Currently one pbkdfengine per salsaengine - TODO share the pbkdfengine for several salsaengines\n\t\t\tpbkdfengine P (.hash_clk(hash_clk), .data1(data1), .data2(data2), .data3(data3), .target(targetreg),\n\t\t\t\t.nonce_msb({nonce_chip, nonce_core}), .nonce_out(nonce_out), .golden_nonce_out(slave_nonces[i*32+31:i*32]),\n\t\t\t\t.golden_nonce_match(gn_match), .loadnonce(loadnonce),\n\t\t\t\t.salsa_din(salsa_din), .salsa_dout(salsa_dout), .salsa_busy(salsa_busy), .salsa_result(salsa_result),\n\t\t\t\t.salsa_reset(salsa_reset), .salsa_start(salsa_start), .salsa_shift(salsa_shift));\n\n\t\t\tsalsaengine S (.hash_clk(hash_clk), .reset(salsa_reset), .din(salsa_din), .dout(salsa_dout), .shift(salsa_shift),\n\t\t\t\t.start(salsa_start), .busy(salsa_busy), .result(salsa_result) );\n\t\t\t\t\t\n\t\t\t// Synchronise across clock domains from hash_clk to uart_clk for: assign new_nonces[i] = gn_match;\n\t\t\treg gn_match_toggle = 1'b0;\t\t// hash_clk domain\n\t\t\talways @ (posedge hash_clk)\n\t\t\t\tgn_match_toggle <= gn_match_toggle ^ gn_match;\n\n\t\t\treg gn_match_toggle_d1 = 1'b0;\t// uart_clk domain\n\t\t\treg gn_match_toggle_d2 = 1'b0;\n\t\t\treg gn_match_toggle_d3 = 1'b0;\n\n\t\t\tassign new_nonces[i] = gn_match_toggle_d3 ^ gn_match_toggle_d2;\n\n\t\t\talways @ (posedge uart_clk)\n\t\t\tbegin\n\t\t\t\tgn_match_toggle_d1 <= gn_match_toggle;\n\t\t\t\tgn_match_toggle_d2 <= gn_match_toggle_d1;\n\t\t\t\tgn_match_toggle_d3 <= gn_match_toggle_d2;\n\t\t\tend\n\t\t\t// End of clock domain sync\n\t\tend // for\n\tendgenerate\n\n\t// External miner ports, results appended to the same\n\t// slave_nonces/new_nonces as local ones\n\toutput [EXT_PORTS-1:0] extminer_txd;\n\tinput [EXT_PORTS-1:0]  extminer_rxd;\n\tassign extminer_txd = {EXT_PORTS{RxD}};\n\n\tgenerate\n\t\tgenvar j;\n\t\tfor (j = LOCAL_MINERS; j < SLAVES; j = j + 1)\n\t\tbegin: for_ports\n\t\t\tslave_receive #(.comm_clk_frequency(comm_clk_frequency), .baud_rate(BAUD_RATE)) slrx (.clk(uart_clk), .RxD(extminer_rxd[j-LOCAL_MINERS]), .nonce(slave_nonces[j*32+31:j*32]), .new_nonce(new_nonces[j]));\n\t\tend\n\tendgenerate\n\n\toutput [3:0] led;\n\tassign led[1] = ~RxD;\n\tassign led[2] = ~TxD;\n\tassign led[3] = ~ (TMP_SCL | TMP_SDA | TMP_ALERT);\t// IDLE LED - held low (the TMP pins are PULLUP, this is a fudge to\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// avoid warning about unused inputs)\n\n\t// Light up only from locally found nonces, not ext_port results\n\tpwm_fade pf (.clk(uart_clk), .trigger(|new_nonces[LOCAL_MINERS-1:0]), .drive(led[0]));\n   \nendmodule\n"
  },
  {
    "path": "experimental/LX150-SPLIT/pbkdfengine.v",
    "content": "/* pbkdfengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`define ICARUS\t\t\t// Comment this out when using the altera virtual_wire interface in ltcminer.v\n\t\n`timescale 1ns/1ps\n\nmodule pbkdfengine\n\t(hash_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce,\n\t\t\tsalsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift);\n\n\tinput hash_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\n\toutput [31:0] nonce_out;\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\n\tinput salsa_dout;\n\toutput salsa_din;\n\tinput salsa_busy, salsa_result;\n\toutput salsa_reset;\n\toutput salsa_start;\n\toutput reg salsa_shift = 1'b0;\n\n\treg poweron_reset = 1'b1;\n\treg reset = 1'b1;\n\tassign salsa_reset = reset;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tpoweron_reset <= 1'b0;\n\t\treset <= poweron_reset;\t\t\t// Ensures a full clock cycle for reset\n\tend\n\t\n\t`ifndef ICARUS\n\treg [31:0] nonce_previous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\t`endif\n\n\t`ifndef NOMULTICORE\n\t`ifdef SIM\n\t\treg [27:0] nonce_cnt = 28'h318f;\t// Start point for simulation\n\t`else\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t`endif\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\tassign nonce_out = nonce;\n\n\treg [31:0] nonce_1 = 32'd0;\t\t// Pipeline nonce since needed for final PBKDF2_SHA256_80_128_32\n\treg [31:0] nonce_2 = 32'd0;\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [31:0] blockcnt = 32'd0;\t// Takes values 1..4 for block iteration (NB could hardwire top 29 bits)\n\treg [1023:0] Xbuf = 1024'd0;\t// Shared input/output buffer and shift register\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\tassign salsa_din = Xbuf[1023];\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\t\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(hash_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\n\t// reg Clr_SMixInRdy = 1'b0;\t// Fudge this for now...\n\treg salsa_busy_d1 = 1'b0;\n\twire Clr_SMixInRdy;\n\tassign Clr_SMixInRdy = SMixInRdy_state & salsa_busy & ~salsa_busy_d1;\t// Clear on transition to busy\n\t\n\t// reg Set_SMixOutRdy = 1'b0;\t// Fudge this for now...\n\treg salsa_result_d1 = 1'b0;\n\twire Set_SMixOutRdy;\n\tassign Set_SMixOutRdy = ~SMixOutRdy_state & salsa_result & ~salsa_result_d1;\n\t\n\treg Clr_SMixOutRdy = 1'b0;\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tsalsa_busy_d1 <= salsa_busy;\n\t\tsalsa_result_d1 <= salsa_result;\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\tend\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\tassign salsa_start = SMixInRdy;\n\t\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz)\n\t\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_SHIFT_IN=22, S_SHIFT_OUT=41,\t\t\t\t\t\t\t// Direction relative to salsa unit\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\treg start_output = 0;\n\treg\t[10:0]shift_count = 0;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\n\t\t`ifdef ICARUS\n\t\tif (loadnonce)\t\t\t\t// Separate clock domains means comparison is unsafe\n\t\t`else\n\t\tif (loadnonce || (nonce_previous_load != data3[127:96]))\n\t\t`endif\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_previous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\t`ifndef ICARUS\n\t\t\tnonce_previous_load <= data3[127:96];\n\t\t\t`endif\n\t\tend\n\t\t\n\t\tif (reset == 1'b1)\n\t\tbegin\n\t\t\tstate <= S_IDLE;\n\t\t\tstart_output <= 1'b0;\n\t\t\tsalsa_shift <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tshift_count <= 0;\n\t\t\t\t\tif (SMixOutRdy & ~start_output)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tstate <= S_SHIFT_OUT;\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (start_output ||\t// Process output\n\t\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'b0;\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\t\tblockcnt <= 32'd1;\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_2 : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tblockcnt, nonce, data3[95:0] };\n\t\t\t\t\t\tblockcnt <= blockcnt + 1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\t\t\n\t\t\t\tS_B6: begin\t// Shift output into X buffer from MSB->LSB\n\t\t\t\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\t\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\t\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\t\t\t\tXbuf[1023:768] <= tx_hash;\n\n\t\t\t\t\t\tif (blockcnt == 5)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tnonce_1 <= nonce;\n\t\t\t\t\t\t\tnonce_2 <= nonce_1;\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 28'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 32'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\t\tstate <= S_SHIFT_IN;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\tblockcnt, nonce, data3[95:0] };\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_SHIFT_IN: begin\t\t\t\t\t\t\t// Shifting from PBKDF2_SHA256 to salsa\n\t\t\t\t\t\tsalsa_shift <= 1;\n\t\t\t\t\t\tif (salsa_shift)\n\t\t\t\t\t\t\tXbuf <= { Xbuf[1022:0], salsa_dout };\n\t\t\t\t\t\tshift_count <= shift_count + 1;\n\t\t\t\t\t\tif (shift_count == 1024)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tSet_SMixInRdy <= 1;\t\t\t// Flag salsa to start\n\t\t\t\t\t\t\tsalsa_shift <= 0;\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_SHIFT_OUT: begin\t\t\t\t\t\t\t// Shifting from salsa to PBKDF2_SHA256\n\t\t\t\t\t\t// nonce_2 <= nonce_1;\t\t\t\t// Already done this in S_B6 (MAY need nonce_3 though)\n\t\t\t\t\t\tsalsa_shift <= 1;\n\t\t\t\t\t\tif (salsa_shift)\n\t\t\t\t\t\t\tXbuf <= { Xbuf[1022:0], salsa_dout };\n\t\t\t\t\t\tshift_count <= shift_count + 1;\n\t\t\t\t\t\tif (shift_count == 1024)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1;\t\t\t// Flag self to start\n\t\t\t\t\t\t\tsalsa_shift <= 0;\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_2;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n\tend\n\n\t// MixOut is little-endian word format to match scrypt.c so convert back to big-endian\n\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] mix;\n\t\tassign mix = Xbuf[`IDX(i)];\t\t// NB MixOut now shares Xbuf since shifted in/out\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\nendmodule"
  },
  {
    "path": "experimental/LX150-SPLIT/salsaengine.v",
    "content": "/* salsaengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n// HALFRAM is slightly lazily implemented as some regs/wires are not commented\n// out for the full scratchpad, the synthesizer should remove most of these.\n\n`define HALFRAM\t\t// Select between 1024kBit and 512kBit ram\n\n`timescale 1ns/1ps\n\nmodule salsaengine (hash_clk, reset, din, dout, shift, start, busy, result );\n\n\tinput hash_clk, reset, din, shift, start;\n\toutput reg busy = 1'b0;\n\toutput reg result = 1'b0;\n\toutput dout;\n\n\tparameter XSnull = 0, XSload = 1, XSmix = 2, XSram = 4;\t\t// one-hot\n\treg [2:0] XCtl = XSnull;\n\t\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\tparameter R_IDLE=0, R_START=1, R_WRITE=2, R_MIX=4, R_INT=8;\t\t// Try explicit one-hot\n\treg [3:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg [5:0] mcount = 5'd0;\t// Salsa latency\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs\n\treg mixfeedback = 1'b0;\n\treg addrsourceMix = 1'b0;\n\treg addrsourceSave = 1'b0;\n\treg xoren = 1'b1;\n\treg\t [1:0] intcycles = 2'b0;\t// Number of interpolation cycles required\n\n\twire [511:0] Xmix;\n\treg [511:0] X0;\n\treg [511:0] X1;\n\twire [511:0] X0in;\n\twire [511:0] X1in;\n\treg [1023:0] salsaShiftReg;\n\tassign dout = salsaShiftReg[1023];\n\n\t// Convert salsaShiftReg to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = salsaShiftReg[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\tend\n\tendgenerate\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of HALFRAM mode\n\treg [9:0] writeaddr = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\t`ifdef HALFRAM\n\t\tparameter ADDRBITS = 9;\n\t`else\n\t\tparameter ADDRBITS = 10;\n\t`endif\n\n\twire [ADDRBITS-1:0]ram_addr;\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\treg ram_wren = 1'b0;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\t`ifdef HALFRAM\n\t\t// This is the half scratchpad version\n\t\t// Top ram address is reserved for X0Save/X1save, so adjust\n\t\twire [8:0] adj_addr = (Xmix[9:1] == 9'h1ff) ? 9'h1fe : Xmix[9:1];\n\t\tassign ram_addr = addrsourceMix ? (addrsourceSave ? 9'h1ff : adj_addr) : writeaddr[9:1];\t// LSB is ignored\n\t`else\n\t\t// This is the full scratchpad version\n\t\tassign ram_addr = addrsourceMix ? Xmix[9:0] : writeaddr;\n\t`endif\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (ram_addr, ram_clk, ram1_din, ram_wren, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (ram_addr, ram_clk, ram2_din, ram_wren, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (ram_addr, ram_clk, ram3_din, ram_wren, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (ram_addr, ram_clk, ram4_din, ram_wren, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = { X1, X0} ;\t// Registered input\n\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, mixfeedback, X0, X1, Xmix);\n\n\t// Main multiplexer\n\twire [511:0] Zbits;\n\tassign Zbits = {512{xoren}};\t\t// xoren enables xor from ram (else we load from ram)\n\t\n\t// With luck the synthesizer will interpret this correctly as one-hot control (TODO use explicit signal bits eg Xctl[0] for XSload)\n\tassign X0in = (XCtl==XSmix) ? X1 : (XCtl==XSram) ? (X0 & Zbits) ^ ramout[511:0] : (XCtl==XSload) ? X[511:0] : X0;\n\tassign X1in = (XCtl==XSmix) ? Xmix : (XCtl==XSram) ? (X1 & Zbits) ^ ramout[1023:512] : (XCtl==XSload) ? X[1023:512] : X1;\n\t\n\t// Salsa FSM - TODO may want to move this into a separate function (for floorplanning), see hashvariant-C\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tX0 <= X0in;\n\t\tX1 <= X1in;\n\t\t\n\t\tXCtl <= XSnull;\t\t\t\t// Default states\n\t\taddrsourceSave <= 0;\n\t\tram_wren <= 0;\n\t\txoren <= 1;\n\t\t\n\t\tif (shift)\n\t\t\tsalsaShiftReg <= { salsaShiftReg[1022:0], din };\n\t\t\n\t\tif (reset == 1'b1)\n\t\tbegin\n\t\t\tmstate <= R_IDLE;\n\t\t\tresult <= 1'b0;\t\t\t// Needed else we won't load first input data\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\twriteaddr <= 0;\n\t\t\t\t\tmcount <= 0;\n\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\tif (start)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (~result)\n\t\t\t\t\t\t\tXCtl <= XSload;\t\t// First time only (normally done at end of previous salsa cycle=1023)\n\t\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\t\tbusy <= 1'b1;\n\t\t\t\t\t\tresult <= 1'b0;\n\t\t\t\t\t\tmstate <= R_START;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_START: begin\n\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Initial write cycle\n\t\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\t\tend\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\tmcount <= mcount + 6'd1;\n\t\t\t\t\t// 8 stages since salsa takes 4 clock cycles. NB This minimises clock cycles, but adds to\n\t\t\t\t\t// the propagation delay in the salsa. The alternative of adding a cycle or two of latency to\n\t\t\t\t\t// reduce propagation delay is SLOWER due to the extra clocks needed.\n\t\t\t\t\t// Write to ROM every 2nd cycle (NB we are writing previous data here)\n\t\t\t\t\t// NB One extra cycle is performed after ROM is complete to update X0,X1 to inital state for R_MIX\n\t\t\t\t\tif (mcount==0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\t\tif (writeaddr==1023)\n\t\t\t\t\t\t\tdoneROM <= 1'b1;\t\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\t\twriteaddr <= writeaddr + 10'd1;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount==4)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount == 2 || mcount == 6)\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\tif (mcount == 3 || mcount == 7)\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tif (mcount == 6 && doneROM)\t\t\t// Preset the address source one cycle early\n\t\t\t\t\t\taddrsourceMix <= 1'b1;\t\t\t// Remains set for duration of R_MIX\n\t\t\t\t\tif (mcount == 7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tif (doneROM)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tcycle <= 0;\n\t\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t\t`ifdef HALFRAM\n\t\t\t\t\t\t\t// Need this to cover the case of the initial read being interpolated\n\t\t\t\t\t\t\tintcycles <= { 1'b0, Xmix[0] };\t\t// Flag odd addresses (for use in next cycle due to ram latency)\n\t\t\t\t\t\t\tif ( Xmix[9:1] == 9'h1ff )\t\t\t// Highest ram address is reserved for X0save, so\n\t\t\t\t\t\t\t\tintcycles <= { 1'b1, Xmix[0] };\t// need up to 3 interpolations\n\n\t\t\t\t\t\t\tif ( (Xmix[9:1] == 9'h1ff) || Xmix[0])\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t\t// Setup to save X0/X1 to top location of ram\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// NB the !doneROM test is superfluous here as its in the else clause of if(doneROM)\n\t\t\t\t\t\t\t`ifdef HALFRAM\n\t\t\t\t\t\t\t\tif (!writeaddr[0])\t// Do not write on odd cycles (half scratchpad)\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Since registered we preset this here\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// Entered with mixfeedback == 0 (set at mcount==7 above)\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\t// The longest chain is from mixfeedback to ram address input (since XMix is not registered),\n\t\t\t\t\t// again as noted above, extra register stages would simply reduce throughput.\n\t\t\t\t\tmcount <= mcount + 5'd1;\n\t\t\t\t\tif (mcount == 0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\t`ifdef HALFRAM\n\t\t\t\t\t\t\tif (intcycles != 0)\t\t\t// Set in previous cycle\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t// Interpolate\n\t\t\t\t\t\t`endif\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount==1 || mcount==5)\n\t\t\t\t\t\tmixfeedback <= 1;\n\t\t\t\t\tif (mcount == 3 || mcount == 7)\n\t\t\t\t\t\tXCtl <= XSmix;\n\t\t\t\t\tif (mcount == 4 || mcount == 8)\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tif (mcount == 7 && cycle == 1023)\n\t\t\t\t\t\t\tXCtl <= XSload;\t\t\t// Initial load is at mcount==8 else we overwrite input\n\t\t\t\t\tif (mcount == 8)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tcycle <= cycle + 11'd1;\n\t\t\t\t\t\tif (cycle == 1023)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// Pipeline the result so we can start processing the next X input\n\t\t\t\t\t\t\tsalsaShiftReg <= { Xmix, X1 };\t// Simultaneously do XSload (set at mcount==7)\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\tbusy <= 1'b0;\n\t\t\t\t\t\t\tmstate <= R_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t\t`ifdef HALFRAM\n\t\t\t\t\t\t\t// ALSO do this in final step of R_WRITE\n\t\t\t\t\t\t\tintcycles <= { 1'b0, Xmix[0] };\t\t// Flag odd addresses (for use in next cycle due to ram latency)\n\t\t\t\t\t\t\tif ( Xmix[9:1] == 9'h1ff )\t\t\t// Highest ram address is reserved for X0save, so\n\t\t\t\t\t\t\t\tintcycles <= { 1'b1, Xmix[0] };\t// need up to 3 interpolations\n\n\t\t\t\t\t\t\tif ( (Xmix[9:1] == 9'h1ff) || Xmix[0])\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t\t// Setup to save at mcount==0 (also does so entering R_IDLE\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t\t// after cycle==1023 but of no consequence)\n\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t`ifdef HALFRAM\n\t\t\t\tR_INT: begin\n\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\t// Mcount has already been incremented in R_MIX\n\t\t\t\t\tmcount <= mcount + 6'd1;\n\t\t\t\t\tif (mcount==1 || mcount==5)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount == 3 || mcount == 7)\n\t\t\t\t\t\tXCtl <= XSmix;\n\t\t\t\t\tif (mcount == 4 || mcount == 8)\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tif (mcount == 7)\n\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data at mcount==9\n\t\t\t\t\tif (mcount == 8)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (intcycles == 1)\n\t\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Setup to XOR from saved X0/X1 in ram at next cycle\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount == 9)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tintcycles <= intcycles - 1;\n\t\t\t\t\t\tmcount <= 1;\t\t// Skip 0 since done above\n\t\t\t\t\t\tif (intcycles == 1)\n\t\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\t// Else mstate remains at R_INT so we continue interpolating from mcount=1\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t`endif\n\t\t\tendcase\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (mstate == R_MIX && mcount == 8)\n\t\t$display (\"cycle %d Xmix %08x\\n\", cycle, Xmix[511:480]);\n`endif\n\tend\t// always @(posedge hash_clk)\nendmodule"
  },
  {
    "path": "experimental/README.txt",
    "content": "Experimental hashing cores.\n\nI have several goals here ...\n\n1. Reduce LE count to enable more cores to be fitted. This is easiest for registers which\nare currently used with abandon, but this may not help much as registers come essentially\n\"free\" with the CLB's, though hashvariant-A has had some success in reducing the total LE.\n\n2. Investigate pipelining options for the salsa block. I can't see how this will help the\noverall throughput (in fact I expect it will REDUCE it due to setup/hold overheads on the\nregisters). However it may be possible to push two or more hashing operations concurrently\nthrough the one salsa block which may be useful in increasing the throughput of a single\ncore (though this will be constrained by the need for reduced scratchpad sizes to fit the\nconcurrent hashes into ram).\n\n3. Use of onboard SDRAM on the DE0-Nano. Initial calculations show a lower throughput than\nthe internal ram (due to a 16 bit data path at 166MHz), but if sufficient free LE resource\nare available, an additional core could supplement the core using onchip RAM. It will\nneed a rather complex interface (needing to use burst-mode to maximise speed), so it will\nbe a rather more advanced project, but at least we don't need to worry about doing refresh\nas each hash is completed well within the refresh timeout limits.\n\nContents (chronological order)\n------------------------------\nNB These are LX150 Icarus/Lancelot ports (apart from the later entries for Ztex/CM1 etc)\n\nhashvariant-A.v    Uses RAM to reduce register count by eliminating X0Save, X1Save\n\nhashvariant-B.v    Pipelined 2x clock speed (NOT interleaving hashes). NB performance is\n                   halved due to the need for 2 clocks per salsa-mix. Uses salsa-B.v\n\t\t\t\t   \nhashvariant-C.v    As B, but pushes two hashes simultaneously through the pipeline. Also\n                   uses salsa-B.v NB This is a prototype design, the hash scheduling FSM\n                   is totally INSANE (a tribute to NASA's skycrane perhaps).\n\nLX150-SPLIT        Separates the pbkdf and salsa engines into separate modules linked by\n                   a one bit serial bus to reduce routing congestion. This will form the\n                   basis of ongoing work on further pipelining of the salsa.\n\nLX150-EIGHT-A      Fully pipelined salsa with 8 threads. Slow and somewhat buggy (see\n                   the README). Major rework is required, will use -B, -C suffixes.\n \nLX150-EIGHT-B      Separate clock domains for pbkbd and salsa, dynamic clock speed (yay)!\n\nLX150-EIGHT-C      Ten stage pipeline (still only 8 threads). Not usefully faster.\n\nLX150-SLOWEIGHT-A  A return to the original slow clocked salsa core, but now with eight\n                   threads. This gets just under 10kHash/sec per LX150 though only one\n                   core sucessfully routes (there is sufficient LUT resource for a\n                   second, but the router cannot route it, perhaps a more aggressive\n                   planahead scheme will work).\n\nLX150-SLOWSIXTEEN-A Added a pipeline stage between column and row operations. Sixteen\n                   threads, and this time a second core does fit. Clocks at 50Mhz (the\n                   default is 25MHz, so increase it at runtime via the mining script)\n                   giving aroung 16khash/sec per LX150 (33khash/sec total for Lancelot).\n\nLX150-SIXTYFOUR-A  Included for completeness, its performance is quite poor.\n\nZTEX               Old NON-working code for ztex 1.15b - DO NOT USE\n\nZtex-1.15y         Working Ztex 1.15y port plus subfolder for cgminer 3.1.1\n\nCM1                Working Carinsmore CM1 port (use same cgminer as Ztex-1.15y above)\n\nDE2-115-SLOWSIXTEEN Experimental port (untested) requested by forum user Dork and\n                   intended as a bridge to a Cyclone V SOCKit port.\n\nThe later versions (LX150-EIGHT onwards) are built in PlanAhead version 14.4 (32 bits)\nusing the following modified synthesis settings (strategy defined in Tools/Options) ...\n\nregister balancing = yes\nregister duplication = yes (already in default)\nresource sharing = no\nequivalent register removal = no\n\nThe constraint on hash_clk is VERY lax at 10MHz to facilitate a quick build. You will\nneed to increase this for a better FMAX, in conjunction with tuning the implementation\nstrategy (for example try setting different values for the tables option -t).\n\nThe Ztex-1.15y requires special build instructions, see the README."
  },
  {
    "path": "experimental/ZTEX/README.txt",
    "content": "ZTEX port based on http://www.ztex.de/btcminer/ZtexBTCMiner-121126.tar.bz2\n\nNB This is UNTESTED code uploaded for discussion with vpereira and intended\nfor a ZTEX1.15b board with a spartan LX75 device.\n\nSee https://github.com/vpereira/FPGA-Litecoin-Miner/tree/master/ZTEX1.15b\n\nUse with the following ...\n\nsource/hashcore.v\nsource/salsa.v\nsource/sha256_transform.v\nsource/sha-256-functions.v\nICARUS-LX150/xilinx_ram.v\n\nPackage is CSG-484 (NOT the FGG-484 used in ICARUS/LANCELOT) xc6slx-75-csg484-3\nNB there is also an xa6slx (automotive version). Do not confuse them.\n\nSeveral changes were required to remove Critical Warnings in implementation ...\n\nRemoved NET \"clk_reset\" from ztex_ufm1_15.ucf\nAdded CLKIN_PERIOD for DCM_CLKGEN and PLL_BASE (calculated for 48MHz oscillator)\n\nI also amended the ucf TS_fxclk_in to 20.8ns to avoid NGBuild warnings, though\nit may be better to amend the CLKIN_PERIOD instead (this was the second try\nat getting these right as my first one set the DCM_CLKGEN output frequency\ndirectly to 25MHz which then broke the PLL_BASE due to VCO being out of range).\n... ADDENDUM, we still get a warning, but now its about 6.24nS not matching\n6.25nS so I think this can safely be ignored.\n\nUtilization is around 20% LUT and 34% RAM on LX75, so multiple cores should\neasily fit but will require a golden_nonce queue. The scheme used for the\naltera virtual_wire port in source/ltcminer.v would probably work OK (its a\nvariation on technohog's hub_core). FMax is reported as 26.2MHz.\n"
  },
  {
    "path": "experimental/ZTEX/ztex_ufm1_15.ucf",
    "content": "NET \"fxclk_in\" TNM_NET = \"fxclk_in\";\nTIMESPEC \"TS_fxclk_in\" = PERIOD \"fxclk_in\" 20.8ns HIGH 50 %;\nNET \"fxclk_in\"  LOC = \"L22\" | IOSTANDARD = LVCMOS33 ;\n\n# input\nNET \"write<0>\"  LOC = \"Y17\" | IOSTANDARD = LVCMOS33 | DRIVE = 12; # PB0\nNET \"write<1>\"  LOC = \"V13\" | IOSTANDARD = LVCMOS33 | DRIVE = 12; # PB1\nNET \"write<2>\"  LOC = \"W13\" | IOSTANDARD = LVCMOS33 | DRIVE = 12; # PB2\nNET \"write<3>\"  LOC = \"AA8\" | IOSTANDARD = LVCMOS33 | DRIVE = 12; # PB3\nNET \"write<4>\"  LOC = \"AB8\" | IOSTANDARD = LVCMOS33 | DRIVE = 12; # PB4\nNET \"write<5>\"  LOC = \"W6\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;  # PB5\nNET \"write<6>\"  LOC = \"Y6\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;  # PB6\nNET \"write<7>\"  LOC = \"Y9\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;  # PB7\n\nNET \"wr_clk\"  LOC = \"AB5\" | IOSTANDARD = LVCMOS33;        # PA6\nNET \"wr_start\" LOC = \"AB17\" | IOSTANDARD = LVCMOS33 ;     # PA7\n\n# dcm\nNET \"dcm_progclk\"  LOC = \"U15\" | IOSTANDARD = LVCMOS33 ;  # PA2\nNET \"dcm_progdata\"  LOC = \"W17\" | IOSTANDARD = LVCMOS33 ; # PA4\nNET \"dcm_progen\"  LOC = \"Y18\" | IOSTANDARD = LVCMOS33 ;   # PA5\n\n#output\nNET \"read<0>\"  LOC = \"V21\" | IOSTANDARD = LVCMOS33 ;  # PD0\nNET \"read<1>\"  LOC = \"V22\" | IOSTANDARD = LVCMOS33 ;  # PD1\nNET \"read<2>\"  LOC = \"U20\" | IOSTANDARD = LVCMOS33 ;  # PD2\nNET \"read<3>\"  LOC = \"U22\" | IOSTANDARD = LVCMOS33 ;  # PD3\nNET \"read<4>\"  LOC = \"R20\" | IOSTANDARD = LVCMOS33 ;  # PD4\nNET \"read<5>\"  LOC = \"R22\" | IOSTANDARD = LVCMOS33 ;  # PD5\nNET \"read<6>\"  LOC = \"P18\" | IOSTANDARD = LVCMOS33 ;  # PD6\nNET \"read<7>\"  LOC = \"P19\" | IOSTANDARD = LVCMOS33 ;  # PD7\n\nNET \"reset\"  LOC = \"G20\" | IOSTANDARD = LVCMOS33 ;     # PC0\nNET \"rd_clk\"  LOC = \"T20\" | IOSTANDARD = LVCMOS33 ;    # PC1\nNET \"pll_stop\"  LOC = \"Y5\" | IOSTANDARD = LVCMOS33 ;   # PC2\n\n# Commented out to avoid critical warning...\n# NET \"clk_reset\"  LOC = \"G19\" | IOSTANDARD = LVCMOS33 ;   # PC4\n\n# unused\n#NET \"\"  LOC = \"AB9\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;  # PC3\n#NET \"\"  LOC = \"G19\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;  # PC4\n#NET \"\"  LOC = \"H20\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;  # PC5\n#NET \"\"  LOC = \"H19\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;  # PC6\n#NET \"\"  LOC = \"H18\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;  # PC7\n\n# debug\n#NET \"green16<0>\"  LOC = \"V20\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<1>\"  LOC = \"Y22\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<2>\"  LOC = \"AA22\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<3>\"  LOC = \"Y21\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<4>\"  LOC = \"W20\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<5>\"  LOC = \"AA20\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<6>\"  LOC = \"V19\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<7>\"  LOC = \"Y19\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<8>\"  LOC = \"V18\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<9>\"  LOC = \"Y15\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<10>\"  LOC = \"W15\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<11>\"  LOC = \"AA14\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<12>\"  LOC = \"AB12\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<13>\"  LOC = \"AA10\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<14>\"  LOC = \"T14\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n#NET \"green16<15>\"  LOC = \"W12\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;\n\n# TIG's\nNET \"inbuf[*]\" TIG;\nNET \"m/golden_nonce[*]\" TIG;\n\n############################################################################\n# LEDS \n############################################################################\n#NET \"LED<0>\"  LOC = \"R1\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;\n#NET \"LED<1>\"  LOC = \"T1\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;\n#NET \"LED<2>\"  LOC = \"U1\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;\n#NET \"LED<3>\"  LOC = \"V1\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;\n#NET \"LED<4>\"  LOC = \"W1\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;\n#NET \"LED<5>\"  LOC = \"Y1\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;\n#NET \"LED<6>\"  LOC = \"AB2\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;\n#NET \"LED<7>\"  LOC = \"AA2\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;\n"
  },
  {
    "path": "experimental/ZTEX/ztex_ufm1_15b1_litecoin.v",
    "content": "/*!\n   btcminer -- BTCMiner for ZTEX USB-FPGA Modules: HDL code for ZTEX USB-FPGA Module 1.15b (one double hash pipe)\n   Copyright (C) 2011 ZTEX GmbH\n   http://www.ztex.de\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License version 3 as\n   published by the Free Software Foundation.\n\n   This program is distributed in the hope that it will be useful, but\n   WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n   General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, see http://www.gnu.org/licenses/.\n!*/\n\nmodule ztex_ufm1_15b1 (fxclk_in, reset, pll_stop,  dcm_progclk, dcm_progdata, dcm_progen,  rd_clk, wr_clk, wr_start, read, write);\n\n\tinput fxclk_in, reset, pll_stop, dcm_progclk, dcm_progdata, dcm_progen, rd_clk, wr_clk, wr_start;\n\tinput [7:0] read;\n\toutput [7:0] write;\n\n\treg [3:0] rd_clk_b, wr_clk_b;\n\treg wr_start_b1, wr_start_b2, reset_buf;\n\treg dcm_progclk_buf, dcm_progdata_buf, dcm_progen_buf;\n\treg [4:0] wr_delay;\n\treg [671:0] inbuf, inbuf_tmp;\n\treg [95:0] outbuf;\n\treg [7:0] read_buf, write_buf;\n\t\n\twire fxclk, clk, dcm_clk, pll_fb, pll_clk0, dcm_locked, pll_reset;\n\twire [31:0] golden_nonce, nonce2, hash2;\n\n\twire [255:0]\tdata1, data2;\n\twire [127:0]\tdata3;\n\twire [31:0]\t\ttarget;\n\n\tassign\t\t\ttarget = inbuf[671:640];\n\tassign\t\t\tdata3 = inbuf[639:512];\n\tassign\t\t\tdata2 = inbuf[511:256];\n\tassign\t\t\tdata1 = inbuf[255:0];\n\t\n\twire\t\t\tgn_match;\t\t\t\t// Just needed for hashcore connection\n\twire\t\t\tloadnonce;\n\n\tassign\t\t\tloadnonce = 1'b0;\t\t// This should be fine, alternatively try...\n\t// assign\t\tloadnonce = reset_buf;\t// You will need `define ICARUS in hashcore.v\n\n\tassign\t\t\thash2 = 32'd0;\t\t\t// Alternatively output final_hash[255:224] from hachcore\n\n\t// Since this is a single core, you may want to `define NOMULTICORE in hashcore.v\n\thashcore M (.hash_clk(clk), .data1(data1), .data2(data2), .data3(data3), .target(target),\n\t\t\t\t\t.nonce_msb(4'd0), .nonce_out(nonce2), .golden_nonce_out(golden_nonce),\n\t\t\t\t\t.golden_nonce_match(gn_match), .loadnonce(loadnonce));\n\n\tBUFG bufg_fxclk (\n          .I(fxclk_in),\n          .O(fxclk)\n        );\n\n\tBUFG bufg_clk (\n          .I(pll_clk0),\n          .O(clk)\n        );\n\n        DCM_CLKGEN #(\n\t\t  .CLKFX_DIVIDE(6),\n          .CLKFX_MULTIPLY(20),\t\t// Gives nominal 160MHz clkfx for 48MHz clk_in\n          .CLKFXDV_DIVIDE(2),\n\t\t  .CLKIN_PERIOD(20.8)\t\t// Added to avoid critical warning (48MHz)\n\t) \n\tdcm0 (\n    \t  .CLKIN(fxclk),\n          .CLKFX(dcm_clk),\n          .FREEZEDCM(1'b0),\n          .PROGCLK(dcm_progclk_buf),\n          .PROGDATA(dcm_progdata_buf),\n          .PROGEN(dcm_progen_buf),\n          .LOCKED(dcm_locked),\n          .RST(1'b0)\n\t);\n\n\tPLL_BASE #(\n    \t    .BANDWIDTH(\"LOW\"),\n    \t    .CLKFBOUT_MULT(5),\n    \t    .CLKOUT0_DIVIDE(32),\t\t// To give 25MHz clk (160 * 5 / 32)\n    \t    .CLKOUT0_DUTY_CYCLE(0.5),\n    \t    .CLK_FEEDBACK(\"CLKFBOUT\"), \n    \t    .COMPENSATION(\"DCM2PLL\"),\n\t    .DIVCLK_DIVIDE(1),\n    \t    .REF_JITTER(0.05),\n\t    .RESET_ON_LOSS_OF_LOCK(\"FALSE\"),\n\t\t.CLKIN_PERIOD(6.25)\t\t\t// Added to avoid critical warning (160Mhz)\n       )\n       pll0 (\n    \t    .CLKFBOUT(pll_fb),\n\t    .CLKOUT0(pll_clk0),\n\t    .CLKFBIN(pll_fb),\n\t    .CLKIN(dcm_clk),\n\t    .RST(pll_reset)\n\t);\n\n\tassign write = write_buf;\n\tassign pll_reset = pll_stop | ~dcm_locked;\n\t\n\talways @ (posedge clk)\n\tbegin\n    \t\tif ( (rd_clk_b[3] == rd_clk_b[2]) && (rd_clk_b[2] == rd_clk_b[1]) && (rd_clk_b[1] != rd_clk_b[0]) )\n\t\tbegin\n\t\t    inbuf_tmp[671:664] <= read_buf;\t\t\t// NB changed from 351 in original\n\t\t    inbuf_tmp[663:0] <= inbuf_tmp[671:8];\n\t\tend;\n\t\tinbuf <= inbuf_tmp;  // due to TIG's\n\t\t    \n\t\tif ( wr_start_b1 && wr_start_b2 )\n\t\tbegin\n   \t\t    wr_delay <= 5'd0;\n\t\tend else \n\t\tbegin\n\t\t    wr_delay[0] <= 1'b1;\n\t\t    wr_delay[4:1] <= wr_delay[3:0];\n\t\tend\n\t\t\n\t\tif ( ! wr_delay[4] ) \n\t\tbegin\n   \t\t    outbuf <= { hash2, nonce2, golden_nonce };\n   \t\tend else\n   \t\tbegin\n\t\t    if ( (wr_clk_b[3] == wr_clk_b[2]) && (wr_clk_b[2] == wr_clk_b[1]) && (wr_clk_b[1] != wr_clk_b[0]) ) \n\t\t\toutbuf[87:0] <= outbuf[95:8];\n   \t\tend\n\n\t\tread_buf <= read;\n\t\twrite_buf <= outbuf[7:0];\n\n\t\trd_clk_b[0] <= rd_clk;\n\t\trd_clk_b[3:1] <= rd_clk_b[2:0];\n\n\t\twr_clk_b[0] <= wr_clk;\n\t\twr_clk_b[3:1] <= wr_clk_b[2:0];\n\n\t\twr_start_b1 <= wr_start;\n\t\twr_start_b2 <= wr_start_b1;\n\n\t\t\n\t\treset_buf <= reset;\n\tend\n\n\talways @ (posedge fxclk)\n\tbegin\n\t\tdcm_progclk_buf <= dcm_progclk;\n\t\tdcm_progdata_buf <= dcm_progdata;\n\t\tdcm_progen_buf <= dcm_progen;\n\tend\n\n\nendmodule\n\n"
  },
  {
    "path": "experimental/Ztex-1-15y/README.txt",
    "content": "Litecoin miner Ztex 1.15y port\n\nA single core experimental bitstream is available at ...\nhttps://www.dropbox.com/s/l1w0flfqs4q1xm8/ztex_ufm1_15y1-ltc-v04-1core-ucf-46-fmax-46.bit\n\nThis performs slightly better than the dual core build as the higher internal clock speed more\nthan makes up for the single core. NB this has a different DCM clock divider, so clock it at\naround 132MHz for roughly 60kHash/sec at the pool.\n\nNB Devices vary so your maximum clock speed may be different to mine. A significant number of per\ndevice HW errors are to be expected due to the way the cgminer ztex driver reports them, however\nthe overall HW error rate should be low (its a different metric). A high overall HW error rate\nindicates excessive clock speed, especially if no shares are being sucessfully submitted.\n\nYou will need the patched version of cgminer-3.1.1 (see README in folder)\n\nWARNING This is experimental code which may DAMAGE YOUR ZTEX BOARD.\nUse at your own risk and monitor the board for overheating (automatic shutdown is disabled due to\nproblems compiling the 2nd PLL which has currently been omitted).\n\nBuild Notes\nThe following bitgen parameter is essential else only three devices will load the bitstream\n-g UnusedPin:Pullnone\n(see http://wiki.ztex.de/doku.php?id=en:ztex_boards:ztex_fpga_boards:porting_to_1_15y)\n\nThe bitstreams were built using ISE 14.4 in PlanAhead with the following non-default parameters\nequivalent register removal = no\nregister balancing = yes\nregister duplication = yes (already in default)\nresource sharing = no\n\nTweak the tables setting for best result (I used -t 4 for the most recent single core build)."
  },
  {
    "path": "experimental/Ztex-1-15y/cgminer-3.1.1/README.txt",
    "content": "FPGA Open Source Litecoin Miner patches for https://github.com/ckolivas/cgminer version 3.1.1\n\nI don't think its appropriate to fork the repository in this case so I will\njust supply patches to specific release versions.\n\nWARNING - This is a VERY rough initial port. Its horribly buggy.\nIn particular the icarus (cairnsmore) hash rate reported is completely wrong.\n\nCompilation\nOpen the official repository (link above) in your browser, click the \"branches\"\ndropdown menu in the middle left of the page, select the \"tags\" tab and scroll down\nto the version required (3.1.1) and select it. Download the zip (right side of page)\nand unzip the archive.\n\nCopy my patch files (from this github folder) into the official cgminer 3.1.1 folder,\nreplacing existing files as necessary. Build as normal, see the README or windows-build.txt\nNB Opencl should be disabled in the configuration (it may work, but I've not tested it)\n./autogen.sh\nCFLAGS=\"-O2\" ./configure --enable-ztex --enable-icarus --enable-scrypt --disable-opencl\nIt will show scrypt as disabled, but this is a lie (my horrible hack hard codes it to be\nenabled since my coding skills are not up to mofifying the config).\n\nPrebuit windows binary (supports both CM1 and ztex) at ...\nhttps://www.dropbox.com/s/zxtzthpmhr5p66i/cgminer.exe\n\nDependancies (DLL) at https://www.dropbox.com/s/unfq6sk8jm3k6j2/cgminer-3.1.1-scryptfpga.zip\n\nTo use the windows version, unzip the dependancies then move cgminer.exe into the folder.\nCopy the bitstream folder from the official cgminer-3.1.1 distribution.\nIMPORTANT Replace ztex_ufm1_15y1.bit with the litecoin bitstream (it must have exactly this name)\n\nYou will need to install the WinUSB driver using zadig which is available at\nhttp://sourceforge.net/projects/libwdi/files/zadig/\n\nRun as ...\ncgminer --scrypt --disable-gpu --url pool:port --userpass username:password 2>log.txt\n\nNotes:\nShould you have problems, redirect the stderr output to log.txt and examine this for messages.\nDo not use this for GPU mining as it will not work.\nDo not use this for bitcoin mining as it will not work.\nThe --debug and --verbose switches may crash the program in windows. Using the -T switch\nperhaps will work around this (it disables curses).\n\nZtex\nOnly the ztex 1.15y board is supported. Frequency management is automatic using the\nsame algorithm as bitcoin. It can be overriden by the --ztex-clock option as follows\n--ztex-clock 120:140\tsets initial clock of 120MHz, max of 140Mhz\n--ztex-clock 128:128\tfixed clock speed of 128MHz\n--ztex-clock 120:140,124:132,128:128,120:120\tset individual fpga device speeds\nI don't know if this will work for multiple boards, but its done the same way as\nthe icarus options so with luck it will be OK.\nThe clock resolution is 4MHz (rounds down) and the valid range is 100MHz to 250MHz.\nIf --ztex-clock is not used the default range is 124MHz to 196MHz.\nSetting both initial and max speeds the same will disable automatic changes.\nNB The clock speed is divided by 4 internally for hashing purposes.\n\nCairnsmore\nCairnsmore CM1 will be detected as icarus\nUse the -S option eg.  -S \\\\.\\COM20 -S \\\\.\\COM21 -S \\\\.\\COM22 -S \\\\.\\COM23 \nClock speed can be set with --cainsmore-clock which takes a single value eg\n--cainsmore-clock 150\t\t\t\tsets all devices to 150MHz\n--cainsmore-clock 140,145,150,155\tsets individual device speeds\nNB Note the typo --cainsmore-clock rather than --cairnsmore-clock. This is not yet fixed in the\ncgminer code, so take care with the spelling, sorry).\nThe clock resolution is 2.5MHz (rounds down) and the valid range is 50MHz to 300MHz.\nIf --cainsmore-clock is not used the default is 150MHz\nNB The clock speed is divided by 4 internally for hashing purposes.\n\nIt will not work for my current lancelot bitstream, use the python miner instead, however\nthere is now an experimental #define LANCELOT84 in driver-icarus.c that you can uncomment\nto compile a version for the lancelot (it won't then work with CM1). Clock speed can\nbe set using --cainsmore-clock with values around 45 to 50 being appropriate for the dual\ncore bitstream rel-13-icarus-lx150-25Mhz-max-51Mhz.bit\n"
  },
  {
    "path": "experimental/Ztex-1-15y/cgminer-3.1.1/cgminer.c",
    "content": "/*\n * Copyright 2011-2013 Con Kolivas\n * Copyright 2011-2012 Luke Dashjr\n * Copyright 2010 Jeff Garzik\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License as published by the Free\n * Software Foundation; either version 3 of the License, or (at your option)\n * any later version.  See COPYING for more details.\n */\n\n#include \"config.h\"\n#define USE_SCRYPT 1\t// KRAMBLE since it won't enable without OPENCL which I don't have and my\n\t\t\t\t\t\t// coding skillz are not up to modifying the config scripts\n\n#ifdef HAVE_CURSES\n#include <curses.h>\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdbool.h>\n#include <stdint.h>\n#include <unistd.h>\n#include <sys/time.h>\n#include <time.h>\n#include <math.h>\n#include <stdarg.h>\n#include <assert.h>\n#include <signal.h>\n\n#include <sys/stat.h>\n#include <sys/types.h>\n\n#ifndef WIN32\n#include <sys/resource.h>\n#endif\n#include <ccan/opt/opt.h>\n#include <jansson.h>\n#include <curl/curl.h>\n#include <libgen.h>\n#include <sha2.h>\n\n#include \"compat.h\"\n#include \"miner.h\"\n#include \"findnonce.h\"\n#include \"adl.h\"\n#include \"driver-opencl.h\"\n#include \"bench_block.h\"\n\n#ifdef HAVE_OPENCL\t\t\t// KRAMBLE\n#include \"scrypt.h\"\n#else\n#include \"scrypt.c\"\n#endif\n\n#ifdef USE_AVALON\n#include \"driver-avalon.h\"\n#endif\n\n#if defined(unix)\n\t#include <errno.h>\n\t#include <fcntl.h>\n\t#include <sys/wait.h>\n#endif\n\n#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_AVALON) || defined(USE_MODMINER)\n#\tdefine USE_FPGA\n#if defined(USE_ICARUS) || defined(USE_AVALON)\n#\tdefine USE_FPGA_SERIAL\n#endif\n#elif defined(USE_ZTEX)\n#\tdefine USE_FPGA\n#endif\n\nstruct strategies strategies[] = {\n\t{ \"Failover\" },\n\t{ \"Round Robin\" },\n\t{ \"Rotate\" },\n\t{ \"Load Balance\" },\n\t{ \"Balance\" },\n};\n\nstatic char packagename[256];\n\nbool opt_protocol;\nstatic bool opt_benchmark;\nbool have_longpoll;\nbool want_per_device_stats;\nbool use_syslog;\nbool opt_quiet;\nbool opt_realquiet;\nbool opt_loginput;\nbool opt_compact;\nconst int opt_cutofftemp = 95;\nint opt_log_interval = 5;\nint opt_queue = 1;\nint opt_scantime = -1;\nint opt_expiry = 120;\nstatic const bool opt_time = true;\nunsigned long long global_hashrate;\n\n#if defined(HAVE_OPENCL) || defined(USE_USBUTILS)\nint nDevs;\n#endif\n#ifdef HAVE_OPENCL\nint opt_dynamic_interval = 7;\nint opt_g_threads = -1;\nint gpu_threads;\n#ifdef USE_SCRYPT\nbool opt_scrypt;\n#endif\n#endif\n\n#ifndef HAVE_OPENCL\t\t// KRAMBLE\n#ifdef USE_SCRYPT\nbool opt_scrypt;\n#endif\n#endif\n\nbool opt_restart = true;\nstatic bool opt_nogpu;\n\nstruct list_head scan_devices;\nstatic signed int devices_enabled;\nstatic bool opt_removedisabled;\nint total_devices;\nstruct cgpu_info **devices;\nbool have_opencl;\nint mining_threads;\nint num_processors;\n#ifdef HAVE_CURSES\nbool use_curses = true;\n#else\nbool use_curses;\n#endif\nstatic bool opt_submit_stale = true;\nstatic int opt_shares;\nbool opt_fail_only;\nstatic bool opt_fix_protocol;\nbool opt_autofan;\nbool opt_autoengine;\nbool opt_noadl;\nchar *opt_api_allow = NULL;\nchar *opt_api_groups;\nchar *opt_api_description = PACKAGE_STRING;\nint opt_api_port = 4028;\nbool opt_api_listen;\nbool opt_api_network;\nbool opt_delaynet;\nbool opt_disable_pool;\nchar *opt_icarus_options = NULL;\nchar *opt_icarus_timing = NULL;\nchar *opt_cainsmore_clock = NULL;\t// KRAMBLE\nchar *opt_ztex_clock = NULL;\t\t// KRAMBLE\nbool opt_worktime;\n#ifdef USE_AVALON\nchar *opt_avalon_options = NULL;\n#endif\n#ifdef USE_USBUTILS\nchar *opt_usb_select = NULL;\nint opt_usbdump = -1;\nbool opt_usb_list_all;\n#endif\n\nchar *opt_kernel_path;\nchar *cgminer_path;\n\n#if defined(USE_BITFORCE)\nbool opt_bfl_noncerange;\n#endif\n#define QUIET\t(opt_quiet || opt_realquiet)\n\nstruct thr_info *control_thr;\nstruct thr_info **mining_thr;\nstatic int gwsched_thr_id;\nstatic int stage_thr_id;\nstatic int watchpool_thr_id;\nstatic int watchdog_thr_id;\n#ifdef HAVE_CURSES\nstatic int input_thr_id;\n#endif\nint gpur_thr_id;\nstatic int api_thr_id;\n#ifdef USE_USBUTILS\nstatic int hotplug_thr_id;\n#endif\nstatic int total_control_threads;\nbool hotplug_mode;\nstatic int new_devices;\nstatic int new_threads;\nstatic int start_devices;\nint hotplug_time = 5;\n\n#ifdef USE_USBUTILS\npthread_mutex_t cgusb_lock;\n#endif\n\npthread_mutex_t hash_lock;\nstatic pthread_mutex_t *stgd_lock;\npthread_mutex_t console_lock;\ncglock_t ch_lock;\nstatic pthread_rwlock_t blk_lock;\nstatic pthread_mutex_t sshare_lock;\n\npthread_rwlock_t netacc_lock;\npthread_rwlock_t mining_thr_lock;\npthread_rwlock_t devices_lock;\n\nstatic pthread_mutex_t lp_lock;\nstatic pthread_cond_t lp_cond;\n\npthread_mutex_t restart_lock;\npthread_cond_t restart_cond;\n\npthread_cond_t gws_cond;\n\ndouble total_mhashes_done;\nstatic struct timeval total_tv_start, total_tv_end;\n\ncglock_t control_lock;\npthread_mutex_t stats_lock;\n\nint hw_errors;\nint total_accepted, total_rejected, total_diff1;\nint total_getworks, total_stale, total_discarded;\ndouble total_diff_accepted, total_diff_rejected, total_diff_stale;\nstatic int staged_rollable;\nunsigned int new_blocks;\nstatic unsigned int work_block;\nunsigned int found_blocks;\n\nunsigned int local_work;\nunsigned int total_go, total_ro;\n\nstruct pool **pools;\nstatic struct pool *currentpool = NULL;\n\nint total_pools, enabled_pools;\nenum pool_strategy pool_strategy = POOL_FAILOVER;\nint opt_rotate_period;\nstatic int total_urls, total_users, total_passes, total_userpasses;\n\nstatic\n#ifndef HAVE_CURSES\nconst\n#endif\nbool curses_active;\n\nstatic char current_block[40];\n\n/* Protected by ch_lock */\nstatic char *current_hash;\nchar *current_fullhash;\n\nstatic char datestamp[40];\nstatic char blocktime[32];\nstruct timeval block_timeval;\nstatic char best_share[8] = \"0\";\ndouble current_diff = 0xFFFFFFFFFFFFFFFFULL;\nstatic char block_diff[8];\nuint64_t best_diff = 0;\n\nstruct block {\n\tchar hash[40];\n\tUT_hash_handle hh;\n\tint block_no;\n};\n\nstatic struct block *blocks = NULL;\n\n\nint swork_id;\n\n/* For creating a hash database of stratum shares submitted that have not had\n * a response yet */\nstruct stratum_share {\n\tUT_hash_handle hh;\n\tbool block;\n\tstruct work *work;\n\tint id;\n\ttime_t sshare_time;\n};\n\nstatic struct stratum_share *stratum_shares = NULL;\n\nchar *opt_socks_proxy = NULL;\n\nstatic const char def_conf[] = \"cgminer.conf\";\nstatic char *default_config;\nstatic bool config_loaded;\nstatic int include_count;\n#define JSON_INCLUDE_CONF \"include\"\n#define JSON_LOAD_ERROR \"JSON decode of file '%s' failed\\n %s\"\n#define JSON_LOAD_ERROR_LEN strlen(JSON_LOAD_ERROR)\n#define JSON_MAX_DEPTH 10\n#define JSON_MAX_DEPTH_ERR \"Too many levels of JSON includes (limit 10) or a loop\"\n\n#if defined(unix)\n\tstatic char *opt_stderr_cmd = NULL;\n\tstatic int forkpid;\n#endif // defined(unix)\n\nbool ping = true;\n\nstruct sigaction termhandler, inthandler;\n\nstruct thread_q *getq;\n\nstatic int total_work;\nstruct work *staged_work = NULL;\n\nstruct schedtime {\n\tbool enable;\n\tstruct tm tm;\n};\n\nstruct schedtime schedstart;\nstruct schedtime schedstop;\nbool sched_paused;\n\nstatic bool time_before(struct tm *tm1, struct tm *tm2)\n{\n\tif (tm1->tm_hour < tm2->tm_hour)\n\t\treturn true;\n\tif (tm1->tm_hour == tm2->tm_hour && tm1->tm_min < tm2->tm_min)\n\t\treturn true;\n\treturn false;\n}\n\nstatic bool should_run(void)\n{\n\tstruct timeval tv;\n\tstruct tm *tm;\n\n\tif (!schedstart.enable && !schedstop.enable)\n\t\treturn true;\n\n\tcgtime(&tv);\n\tconst time_t tmp_time = tv.tv_sec;\n\ttm = localtime(&tmp_time);\n\tif (schedstart.enable) {\n\t\tif (!schedstop.enable) {\n\t\t\tif (time_before(tm, &schedstart.tm))\n\t\t\t\treturn false;\n\n\t\t\t/* This is a once off event with no stop time set */\n\t\t\tschedstart.enable = false;\n\t\t\treturn true;\n\t\t}\n\t\tif (time_before(&schedstart.tm, &schedstop.tm)) {\n\t\t\tif (time_before(tm, &schedstop.tm) && !time_before(tm, &schedstart.tm))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t} /* Times are reversed */\n\t\tif (time_before(tm, &schedstart.tm)) {\n\t\t\tif (time_before(tm, &schedstop.tm))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\t/* only schedstop.enable == true */\n\tif (!time_before(tm, &schedstop.tm))\n\t\treturn false;\n\treturn true;\n}\n\nvoid get_datestamp(char *f, struct timeval *tv)\n{\n\tstruct tm *tm;\n\n\tconst time_t tmp_time = tv->tv_sec;\n\ttm = localtime(&tmp_time);\n\tsprintf(f, \"[%d-%02d-%02d %02d:%02d:%02d]\",\n\t\ttm->tm_year + 1900,\n\t\ttm->tm_mon + 1,\n\t\ttm->tm_mday,\n\t\ttm->tm_hour,\n\t\ttm->tm_min,\n\t\ttm->tm_sec);\n}\n\nvoid get_timestamp(char *f, struct timeval *tv)\n{\n\tstruct tm *tm;\n\n\tconst time_t tmp_time = tv->tv_sec;\n\ttm = localtime(&tmp_time);\n\tsprintf(f, \"[%02d:%02d:%02d]\",\n\t\ttm->tm_hour,\n\t\ttm->tm_min,\n\t\ttm->tm_sec);\n}\n\nstatic void applog_and_exit(const char *fmt, ...)\n{\n\tva_list ap;\n\n\tva_start(ap, fmt);\n\tvapplog(LOG_ERR, fmt, ap);\n\tva_end(ap);\n\texit(1);\n}\n\nstatic pthread_mutex_t sharelog_lock;\nstatic FILE *sharelog_file = NULL;\n\nstruct thr_info *get_thread(int thr_id)\n{\n\tstruct thr_info *thr;\n\n\trd_lock(&mining_thr_lock);\n\tthr = mining_thr[thr_id];\n\trd_unlock(&mining_thr_lock);\n\n\treturn thr;\n}\n\nstatic struct cgpu_info *get_thr_cgpu(int thr_id)\n{\n\tstruct thr_info *thr = get_thread(thr_id);\n\n\treturn thr->cgpu;\n}\n\nstruct cgpu_info *get_devices(int id)\n{\n\tstruct cgpu_info *cgpu;\n\n\trd_lock(&devices_lock);\n\tcgpu = devices[id];\n\trd_unlock(&devices_lock);\n\n\treturn cgpu;\n}\n\nstatic void sharelog(const char*disposition, const struct work*work)\n{\n\tchar *target, *hash, *data;\n\tstruct cgpu_info *cgpu;\n\tunsigned long int t;\n\tstruct pool *pool;\n\tint thr_id, rv;\n\tchar s[1024];\n\tsize_t ret;\n\n\tif (!sharelog_file)\n\t\treturn;\n\n\tthr_id = work->thr_id;\n\tcgpu = get_thr_cgpu(thr_id);\n\tpool = work->pool;\n\tt = (unsigned long int)(work->tv_work_found.tv_sec);\n\ttarget = bin2hex(work->target, sizeof(work->target));\n\thash = bin2hex(work->hash, sizeof(work->hash));\n\tdata = bin2hex(work->data, sizeof(work->data));\n\n\t// timestamp,disposition,target,pool,dev,thr,sharehash,sharedata\n\trv = snprintf(s, sizeof(s), \"%lu,%s,%s,%s,%s%u,%u,%s,%s\\n\", t, disposition, target, pool->rpc_url, cgpu->drv->name, cgpu->device_id, thr_id, hash, data);\n\tfree(target);\n\tfree(hash);\n\tfree(data);\n\tif (rv >= (int)(sizeof(s)))\n\t\ts[sizeof(s) - 1] = '\\0';\n\telse if (rv < 0) {\n\t\tapplog(LOG_ERR, \"sharelog printf error\");\n\t\treturn;\n\t}\n\n\tmutex_lock(&sharelog_lock);\n\tret = fwrite(s, rv, 1, sharelog_file);\n\tfflush(sharelog_file);\n\tmutex_unlock(&sharelog_lock);\n\n\tif (ret != 1)\n\t\tapplog(LOG_ERR, \"sharelog fwrite error\");\n}\n\nstatic char *getwork_req = \"{\\\"method\\\": \\\"getwork\\\", \\\"params\\\": [], \\\"id\\\":0}\\n\";\n\nstatic char *gbt_req = \"{\\\"id\\\": 0, \\\"method\\\": \\\"getblocktemplate\\\", \\\"params\\\": [{\\\"capabilities\\\": [\\\"coinbasetxn\\\", \\\"workid\\\", \\\"coinbase/append\\\"]}]}\\n\";\n\n/* Return value is ignored if not called from add_pool_details */\nstruct pool *add_pool(void)\n{\n\tstruct pool *pool;\n\n\tpool = calloc(sizeof(struct pool), 1);\n\tif (!pool)\n\t\tquit(1, \"Failed to malloc pool in add_pool\");\n\tpool->pool_no = pool->prio = total_pools;\n\tpools = realloc(pools, sizeof(struct pool *) * (total_pools + 2));\n\tpools[total_pools++] = pool;\n\tmutex_init(&pool->pool_lock);\n\tif (unlikely(pthread_cond_init(&pool->cr_cond, NULL)))\n\t\tquit(1, \"Failed to pthread_cond_init in add_pool\");\n\tcglock_init(&pool->data_lock);\n\tmutex_init(&pool->stratum_lock);\n\tcglock_init(&pool->gbt_lock);\n\tINIT_LIST_HEAD(&pool->curlring);\n\n\t/* Make sure the pool doesn't think we've been idle since time 0 */\n\tpool->tv_idle.tv_sec = ~0UL;\n\n\tpool->rpc_req = getwork_req;\n\tpool->rpc_proxy = NULL;\n\n\treturn pool;\n}\n\n/* Pool variant of test and set */\nstatic bool pool_tset(struct pool *pool, bool *var)\n{\n\tbool ret;\n\n\tmutex_lock(&pool->pool_lock);\n\tret = *var;\n\t*var = true;\n\tmutex_unlock(&pool->pool_lock);\n\n\treturn ret;\n}\n\nbool pool_tclear(struct pool *pool, bool *var)\n{\n\tbool ret;\n\n\tmutex_lock(&pool->pool_lock);\n\tret = *var;\n\t*var = false;\n\tmutex_unlock(&pool->pool_lock);\n\n\treturn ret;\n}\n\nstruct pool *current_pool(void)\n{\n\tstruct pool *pool;\n\n\tcg_rlock(&control_lock);\n\tpool = currentpool;\n\tcg_runlock(&control_lock);\n\n\treturn pool;\n}\n\nchar *set_int_range(const char *arg, int *i, int min, int max)\n{\n\tchar *err = opt_set_intval(arg, i);\n\n\tif (err)\n\t\treturn err;\n\n\tif (*i < min || *i > max)\n\t\treturn \"Value out of range\";\n\n\treturn NULL;\n}\n\nstatic char *set_int_0_to_9999(const char *arg, int *i)\n{\n\treturn set_int_range(arg, i, 0, 9999);\n}\n\nstatic char *set_int_1_to_65535(const char *arg, int *i)\n{\n\treturn set_int_range(arg, i, 1, 65535);\n}\n\nstatic char *set_int_0_to_10(const char *arg, int *i)\n{\n\treturn set_int_range(arg, i, 0, 10);\n}\n\nstatic char *set_int_1_to_10(const char *arg, int *i)\n{\n\treturn set_int_range(arg, i, 1, 10);\n}\n\n#ifdef USE_FPGA_SERIAL\nstatic char *add_serial(char *arg)\n{\n\tstring_elist_add(arg, &scan_devices);\n\treturn NULL;\n}\n#endif\n\nstatic char *set_devices(char *arg)\n{\n\tint i = strtol(arg, &arg, 0);\n\n\tif (*arg) {\n\t\tif (*arg == '?') {\n\t\t\tdevices_enabled = -1;\n\t\t\treturn NULL;\n\t\t}\n\t\treturn \"Invalid device number\";\n\t}\n\n\tif (i < 0 || i >= (int)(sizeof(devices_enabled) * 8) - 1)\n\t\treturn \"Invalid device number\";\n\tdevices_enabled |= 1 << i;\n\treturn NULL;\n}\n\nstatic char *set_balance(enum pool_strategy *strategy)\n{\n\t*strategy = POOL_BALANCE;\n\treturn NULL;\n}\n\nstatic char *set_loadbalance(enum pool_strategy *strategy)\n{\n\t*strategy = POOL_LOADBALANCE;\n\treturn NULL;\n}\n\nstatic char *set_rotate(const char *arg, int *i)\n{\n\tpool_strategy = POOL_ROTATE;\n\treturn set_int_range(arg, i, 0, 9999);\n}\n\nstatic char *set_rr(enum pool_strategy *strategy)\n{\n\t*strategy = POOL_ROUNDROBIN;\n\treturn NULL;\n}\n\n/* Detect that url is for a stratum protocol either via the presence of\n * stratum+tcp or by detecting a stratum server response */\nbool detect_stratum(struct pool *pool, char *url)\n{\n\tif (!extract_sockaddr(pool, url))\n\t\treturn false;\n\n\tif (!strncasecmp(url, \"stratum+tcp://\", 14)) {\n\t\tpool->rpc_url = strdup(url);\n\t\tpool->has_stratum = true;\n\t\tpool->stratum_url = pool->sockaddr_url;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nstatic char *set_url(char *arg)\n{\n\tstruct pool *pool;\n\n\ttotal_urls++;\n\tif (total_urls > total_pools)\n\t\tadd_pool();\n\tpool = pools[total_urls - 1];\n\n\targ = get_proxy(arg, pool);\n\n\tif (detect_stratum(pool, arg))\n\t\treturn NULL;\n\n\topt_set_charp(arg, &pool->rpc_url);\n\tif (strncmp(arg, \"http://\", 7) &&\n\t    strncmp(arg, \"https://\", 8)) {\n\t\tchar *httpinput;\n\n\t\thttpinput = malloc(255);\n\t\tif (!httpinput)\n\t\t\tquit(1, \"Failed to malloc httpinput\");\n\t\tstrcpy(httpinput, \"http://\");\n\t\tstrncat(httpinput, arg, 248);\n\t\tpool->rpc_url = httpinput;\n\t}\n\n\treturn NULL;\n}\n\nstatic char *set_user(const char *arg)\n{\n\tstruct pool *pool;\n\n\tif (total_userpasses)\n\t\treturn \"Use only user + pass or userpass, but not both\";\n\ttotal_users++;\n\tif (total_users > total_pools)\n\t\tadd_pool();\n\n\tpool = pools[total_users - 1];\n\topt_set_charp(arg, &pool->rpc_user);\n\n\treturn NULL;\n}\n\nstatic char *set_pass(const char *arg)\n{\n\tstruct pool *pool;\n\n\tif (total_userpasses)\n\t\treturn \"Use only user + pass or userpass, but not both\";\n\ttotal_passes++;\n\tif (total_passes > total_pools)\n\t\tadd_pool();\n\n\tpool = pools[total_passes - 1];\n\topt_set_charp(arg, &pool->rpc_pass);\n\n\treturn NULL;\n}\n\nstatic char *set_userpass(const char *arg)\n{\n\tstruct pool *pool;\n\tchar *updup;\n\n\tif (total_users || total_passes)\n\t\treturn \"Use only user + pass or userpass, but not both\";\n\ttotal_userpasses++;\n\tif (total_userpasses > total_pools)\n\t\tadd_pool();\n\n\tpool = pools[total_userpasses - 1];\n\tupdup = strdup(arg);\n\topt_set_charp(arg, &pool->rpc_userpass);\n\tpool->rpc_user = strtok(updup, \":\");\n\tif (!pool->rpc_user)\n\t\treturn \"Failed to find : delimited user info\";\n\tpool->rpc_pass = strtok(NULL, \":\");\n\tif (!pool->rpc_pass)\n\t\treturn \"Failed to find : delimited pass info\";\n\n\treturn NULL;\n}\n\nstatic char *enable_debug(bool *flag)\n{\n\t*flag = true;\n\t/* Turn on verbose output, too. */\n\topt_log_output = true;\n\treturn NULL;\n}\n\nstatic char *set_schedtime(const char *arg, struct schedtime *st)\n{\n\tif (sscanf(arg, \"%d:%d\", &st->tm.tm_hour, &st->tm.tm_min) != 2)\n\t\treturn \"Invalid time set, should be HH:MM\";\n\tif (st->tm.tm_hour > 23 || st->tm.tm_min > 59 || st->tm.tm_hour < 0 || st->tm.tm_min < 0)\n\t\treturn \"Invalid time set.\";\n\tst->enable = true;\n\treturn NULL;\n}\n\nstatic char* set_sharelog(char *arg)\n{\n\tchar *r = \"\";\n\tlong int i = strtol(arg, &r, 10);\n\n\tif ((!*r) && i >= 0 && i <= INT_MAX) {\n\t\tsharelog_file = fdopen((int)i, \"a\");\n\t\tif (!sharelog_file)\n\t\t\tapplog(LOG_ERR, \"Failed to open fd %u for share log\", (unsigned int)i);\n\t} else if (!strcmp(arg, \"-\")) {\n\t\tsharelog_file = stdout;\n\t\tif (!sharelog_file)\n\t\t\tapplog(LOG_ERR, \"Standard output missing for share log\");\n\t} else {\n\t\tsharelog_file = fopen(arg, \"a\");\n\t\tif (!sharelog_file)\n\t\t\tapplog(LOG_ERR, \"Failed to open %s for share log\", arg);\n\t}\n\n\treturn NULL;\n}\n\nstatic char *temp_cutoff_str = NULL;\n\nchar *set_temp_cutoff(char *arg)\n{\n\tint val;\n\n\tif (!(arg && arg[0]))\n\t\treturn \"Invalid parameters for set temp cutoff\";\n\tval = atoi(arg);\n\tif (val < 0 || val > 200)\n\t\treturn \"Invalid value passed to set temp cutoff\";\n\ttemp_cutoff_str = arg;\n\n\treturn NULL;\n}\n\nstatic void load_temp_cutoffs()\n{\n\tint i, val = 0, device = 0;\n\tchar *nextptr;\n\n\tif (temp_cutoff_str) {\n\t\tfor (device = 0, nextptr = strtok(temp_cutoff_str, \",\"); nextptr; ++device, nextptr = strtok(NULL, \",\")) {\n\t\t\tif (device >= total_devices)\n\t\t\t\tquit(1, \"Too many values passed to set temp cutoff\");\n\t\t\tval = atoi(nextptr);\n\t\t\tif (val < 0 || val > 200)\n\t\t\t\tquit(1, \"Invalid value passed to set temp cutoff\");\n\n\t\t\trd_lock(&devices_lock);\n\t\t\tdevices[device]->cutofftemp = val;\n\t\t\trd_unlock(&devices_lock);\n\t\t}\n\t} else {\n\t\trd_lock(&devices_lock);\n\t\tfor (i = device; i < total_devices; ++i) {\n\t\t\tif (!devices[i]->cutofftemp)\n\t\t\t\tdevices[i]->cutofftemp = opt_cutofftemp;\n\t\t}\n\t\trd_unlock(&devices_lock);\n\n\t\treturn;\n\t}\n\tif (device <= 1) {\n\t\trd_lock(&devices_lock);\n\t\tfor (i = device; i < total_devices; ++i)\n\t\t\tdevices[i]->cutofftemp = val;\n\t\trd_unlock(&devices_lock);\n\t}\n}\n\nstatic char *set_api_allow(const char *arg)\n{\n\topt_set_charp(arg, &opt_api_allow);\n\n\treturn NULL;\n}\n\nstatic char *set_api_groups(const char *arg)\n{\n\topt_set_charp(arg, &opt_api_groups);\n\n\treturn NULL;\n}\n\nstatic char *set_api_description(const char *arg)\n{\n\topt_set_charp(arg, &opt_api_description);\n\n\treturn NULL;\n}\n\n#ifdef USE_ICARUS\nstatic char *set_icarus_options(const char *arg)\n{\n\topt_set_charp(arg, &opt_icarus_options);\n\n\treturn NULL;\n}\n\nstatic char *set_icarus_timing(const char *arg)\n{\n\topt_set_charp(arg, &opt_icarus_timing);\n\n\treturn NULL;\n}\n\nstatic char *set_cainsmore_clock(const char *arg)\n{\n\topt_set_charp(arg, &opt_cainsmore_clock);\n\n\treturn NULL;\n}\n#endif\n\n#ifdef USE_ZTEX\nstatic char *set_ztex_clock(const char *arg)\t// KRAMBLE\n{\n\topt_set_charp(arg, &opt_ztex_clock);\n\n\treturn NULL;\n}\n#endif\n\n#ifdef USE_AVALON\nstatic char *set_avalon_options(const char *arg)\n{\n\topt_set_charp(arg, &opt_avalon_options);\n\n\treturn NULL;\n}\n#endif\n\n#ifdef USE_USBUTILS\nstatic char *set_usb_select(const char *arg)\n{\n\topt_set_charp(arg, &opt_usb_select);\n\n\treturn NULL;\n}\n#endif\n\nstatic char *set_null(const char __maybe_unused *arg)\n{\n\treturn NULL;\n}\n\n/* These options are available from config file or commandline */\nstatic struct opt_table opt_config_table[] = {\n\tOPT_WITH_ARG(\"--api-allow\",\n\t\t     set_api_allow, NULL, NULL,\n\t\t     \"Allow API access only to the given list of [G:]IP[/Prefix] addresses[/subnets]\"),\n\tOPT_WITH_ARG(\"--api-description\",\n\t\t     set_api_description, NULL, NULL,\n\t\t     \"Description placed in the API status header, default: cgminer version\"),\n\tOPT_WITH_ARG(\"--api-groups\",\n\t\t     set_api_groups, NULL, NULL,\n\t\t     \"API one letter groups G:cmd:cmd[,P:cmd:*...] defining the cmds a groups can use\"),\n\tOPT_WITHOUT_ARG(\"--api-listen\",\n\t\t\topt_set_bool, &opt_api_listen,\n\t\t\t\"Enable API, default: disabled\"),\n\tOPT_WITHOUT_ARG(\"--api-network\",\n\t\t\topt_set_bool, &opt_api_network,\n\t\t\t\"Allow API (if enabled) to listen on/for any address, default: only 127.0.0.1\"),\n\tOPT_WITH_ARG(\"--api-port\",\n\t\t     set_int_1_to_65535, opt_show_intval, &opt_api_port,\n\t\t     \"Port number of miner API\"),\n#ifdef HAVE_ADL\n\tOPT_WITHOUT_ARG(\"--auto-fan\",\n\t\t\topt_set_bool, &opt_autofan,\n\t\t\t\"Automatically adjust all GPU fan speeds to maintain a target temperature\"),\n\tOPT_WITHOUT_ARG(\"--auto-gpu\",\n\t\t\topt_set_bool, &opt_autoengine,\n\t\t\t\"Automatically adjust all GPU engine clock speeds to maintain a target temperature\"),\n#endif\n\tOPT_WITHOUT_ARG(\"--balance\",\n\t\t     set_balance, &pool_strategy,\n\t\t     \"Change multipool strategy from failover to even share balance\"),\n\tOPT_WITHOUT_ARG(\"--benchmark\",\n\t\t\topt_set_bool, &opt_benchmark,\n\t\t\t\"Run cgminer in benchmark mode - produces no shares\"),\n#if defined(USE_BITFORCE)\n\tOPT_WITHOUT_ARG(\"--bfl-range\",\n\t\t\topt_set_bool, &opt_bfl_noncerange,\n\t\t\t\"Use nonce range on bitforce devices if supported\"),\n#endif\n#ifdef HAVE_CURSES\n\tOPT_WITHOUT_ARG(\"--compact\",\n\t\t\topt_set_bool, &opt_compact,\n\t\t\t\"Use compact display without per device statistics\"),\n#endif\n\tOPT_WITHOUT_ARG(\"--debug|-D\",\n\t\t     enable_debug, &opt_debug,\n\t\t     \"Enable debug output\"),\n\tOPT_WITH_ARG(\"--device|-d\",\n\t\t     set_devices, NULL, NULL,\n\t             \"Select device to use, (Use repeat -d for multiple devices, default: all)\"),\n\tOPT_WITHOUT_ARG(\"--disable-gpu|-G\",\n\t\t\topt_set_bool, &opt_nogpu,\n#ifdef HAVE_OPENCL\n\t\t\t\"Disable GPU mining even if suitable devices exist\"\n#else\n\t\t\topt_hidden\n#endif\n\t),\n\tOPT_WITHOUT_ARG(\"--disable-rejecting\",\n\t\t\topt_set_bool, &opt_disable_pool,\n\t\t\t\"Automatically disable pools that continually reject shares\"),\n\tOPT_WITH_ARG(\"--expiry|-E\",\n\t\t     set_int_0_to_9999, opt_show_intval, &opt_expiry,\n\t\t     \"Upper bound on how many seconds after getting work we consider a share from it stale\"),\n\tOPT_WITHOUT_ARG(\"--failover-only\",\n\t\t\topt_set_bool, &opt_fail_only,\n\t\t\t\"Don't leak work to backup pools when primary pool is lagging\"),\n\tOPT_WITHOUT_ARG(\"--fix-protocol\",\n\t\t\topt_set_bool, &opt_fix_protocol,\n\t\t\t\"Do not redirect to a different getwork protocol (eg. stratum)\"),\n#ifdef HAVE_OPENCL\n\tOPT_WITH_ARG(\"--gpu-dyninterval\",\n\t\t     set_int_1_to_65535, opt_show_intval, &opt_dynamic_interval,\n\t\t     \"Set the refresh interval in ms for GPUs using dynamic intensity\"),\n\tOPT_WITH_ARG(\"--gpu-platform\",\n\t\t     set_int_0_to_9999, opt_show_intval, &opt_platform_id,\n\t\t     \"Select OpenCL platform ID to use for GPU mining\"),\n\tOPT_WITH_ARG(\"--gpu-threads|-g\",\n\t\t     set_int_1_to_10, opt_show_intval, &opt_g_threads,\n\t\t     \"Number of threads per GPU (1 - 10)\"),\n#ifdef HAVE_ADL\n\tOPT_WITH_ARG(\"--gpu-engine\",\n\t\t     set_gpu_engine, NULL, NULL,\n\t\t     \"GPU engine (over)clock range in Mhz - one value, range and/or comma separated list (e.g. 850-900,900,750-850)\"),\n\tOPT_WITH_ARG(\"--gpu-fan\",\n\t\t     set_gpu_fan, NULL, NULL,\n\t\t     \"GPU fan percentage range - one value, range and/or comma separated list (e.g. 0-85,85,65)\"),\n\tOPT_WITH_ARG(\"--gpu-map\",\n\t\t     set_gpu_map, NULL, NULL,\n\t\t     \"Map OpenCL to ADL device order manually, paired CSV (e.g. 1:0,2:1 maps OpenCL 1 to ADL 0, 2 to 1)\"),\n\tOPT_WITH_ARG(\"--gpu-memclock\",\n\t\t     set_gpu_memclock, NULL, NULL,\n\t\t     \"Set the GPU memory (over)clock in Mhz - one value for all or separate by commas for per card\"),\n\tOPT_WITH_ARG(\"--gpu-memdiff\",\n\t\t     set_gpu_memdiff, NULL, NULL,\n\t\t     \"Set a fixed difference in clock speed between the GPU and memory in auto-gpu mode\"),\n\tOPT_WITH_ARG(\"--gpu-powertune\",\n\t\t     set_gpu_powertune, NULL, NULL,\n\t\t     \"Set the GPU powertune percentage - one value for all or separate by commas for per card\"),\n\tOPT_WITHOUT_ARG(\"--gpu-reorder\",\n\t\t\topt_set_bool, &opt_reorder,\n\t\t\t\"Attempt to reorder GPU devices according to PCI Bus ID\"),\n\tOPT_WITH_ARG(\"--gpu-vddc\",\n\t\t     set_gpu_vddc, NULL, NULL,\n\t\t     \"Set the GPU voltage in Volts - one value for all or separate by commas for per card\"),\n#endif\n#ifdef USE_SCRYPT\n\tOPT_WITH_ARG(\"--lookup-gap\",\n\t\t     set_lookup_gap, NULL, NULL,\n\t\t     \"Set GPU lookup gap for scrypt mining, comma separated\"),\n#endif\n\tOPT_WITH_ARG(\"--intensity|-I\",\n\t\t     set_intensity, NULL, NULL,\n\t\t     \"Intensity of GPU scanning (d or \" _MIN_INTENSITY_STR \" -> \" _MAX_INTENSITY_STR \", default: d to maintain desktop interactivity)\"),\n#endif\n\tOPT_WITH_ARG(\"--hotplug\",\n\t\t     set_int_0_to_9999, NULL, &hotplug_time,\n#ifdef USE_USBUTILS\n\t\t     \"Seconds between hotplug checks (0 means never check)\"\n#else\n\t\t     opt_hidden\n#endif\n\t\t    ),\n#if defined(HAVE_OPENCL) || defined(HAVE_MODMINER)\n\tOPT_WITH_ARG(\"--kernel-path|-K\",\n\t\t     opt_set_charp, opt_show_charp, &opt_kernel_path,\n\t             \"Specify a path to where bitstream and kernel files are\"),\n#endif\n#ifdef HAVE_OPENCL\n\tOPT_WITH_ARG(\"--kernel|-k\",\n\t\t     set_kernel, NULL, NULL,\n\t\t     \"Override sha256 kernel to use (diablo, poclbm, phatk or diakgcn) - one value or comma separated\"),\n#endif\n#ifdef USE_ICARUS\n\tOPT_WITH_ARG(\"--icarus-options\",\n\t\t     set_icarus_options, NULL, NULL,\n\t\t     opt_hidden),\n\tOPT_WITH_ARG(\"--icarus-timing\",\n\t\t     set_icarus_timing, NULL, NULL,\n\t\t     opt_hidden),\n\tOPT_WITH_ARG(\"--cainsmore-clock\",\t\t\t// KRAMBLE\n\t\t     set_cainsmore_clock, NULL, NULL,\n\t\t     opt_hidden),\n#endif\n#ifdef USE_ZTEX\n\tOPT_WITH_ARG(\"--ztex-clock\",\t\t\t\t// KRAMBLE\n\t\t     set_ztex_clock, NULL, NULL,\n\t\t     opt_hidden),\n#endif\n#ifdef USE_AVALON\n\tOPT_WITH_ARG(\"--avalon-options\",\n\t\t     set_avalon_options, NULL, NULL,\n\t\t     opt_hidden),\n#endif\n\tOPT_WITHOUT_ARG(\"--load-balance\",\n\t\t     set_loadbalance, &pool_strategy,\n\t\t     \"Change multipool strategy from failover to efficiency based balance\"),\n\tOPT_WITH_ARG(\"--log|-l\",\n\t\t     set_int_0_to_9999, opt_show_intval, &opt_log_interval,\n\t\t     \"Interval in seconds between log output\"),\n#if defined(unix)\n\tOPT_WITH_ARG(\"--monitor|-m\",\n\t\t     opt_set_charp, NULL, &opt_stderr_cmd,\n\t\t     \"Use custom pipe cmd for output messages\"),\n#endif // defined(unix)\n\tOPT_WITHOUT_ARG(\"--net-delay\",\n\t\t\topt_set_bool, &opt_delaynet,\n\t\t\t\"Impose small delays in networking to not overload slow routers\"),\n\tOPT_WITHOUT_ARG(\"--no-adl\",\n\t\t\topt_set_bool, &opt_noadl,\n#ifdef HAVE_ADL\n\t\t\t\"Disable the ATI display library used for monitoring and setting GPU parameters\"\n#else\n\t\t\topt_hidden\n#endif\n\t\t\t),\n\tOPT_WITHOUT_ARG(\"--no-pool-disable\",\n\t\t\topt_set_invbool, &opt_disable_pool,\n\t\t\topt_hidden),\n\tOPT_WITHOUT_ARG(\"--no-restart\",\n\t\t\topt_set_invbool, &opt_restart,\n#ifdef HAVE_OPENCL\n\t\t\t\"Do not attempt to restart GPUs that hang\"\n#else\n\t\t\topt_hidden\n#endif\n\t),\n\tOPT_WITHOUT_ARG(\"--no-submit-stale\",\n\t\t\topt_set_invbool, &opt_submit_stale,\n\t\t        \"Don't submit shares if they are detected as stale\"),\n\tOPT_WITH_ARG(\"--pass|-p\",\n\t\t     set_pass, NULL, NULL,\n\t\t     \"Password for bitcoin JSON-RPC server\"),\n\tOPT_WITHOUT_ARG(\"--per-device-stats\",\n\t\t\topt_set_bool, &want_per_device_stats,\n\t\t\t\"Force verbose mode and output per-device statistics\"),\n\tOPT_WITHOUT_ARG(\"--protocol-dump|-P\",\n\t\t\topt_set_bool, &opt_protocol,\n\t\t\t\"Verbose dump of protocol-level activities\"),\n\tOPT_WITH_ARG(\"--queue|-Q\",\n\t\t     set_int_0_to_9999, opt_show_intval, &opt_queue,\n\t\t     \"Minimum number of work items to have queued (0+)\"),\n\tOPT_WITHOUT_ARG(\"--quiet|-q\",\n\t\t\topt_set_bool, &opt_quiet,\n\t\t\t\"Disable logging output, display status and errors\"),\n\tOPT_WITHOUT_ARG(\"--real-quiet\",\n\t\t\topt_set_bool, &opt_realquiet,\n\t\t\t\"Disable all output\"),\n\tOPT_WITHOUT_ARG(\"--remove-disabled\",\n\t\t     opt_set_bool, &opt_removedisabled,\n\t         \"Remove disabled devices entirely, as if they didn't exist\"),\n\tOPT_WITH_ARG(\"--retries\",\n\t\t     set_null, NULL, NULL,\n\t\t     opt_hidden),\n\tOPT_WITH_ARG(\"--retry-pause\",\n\t\t     set_null, NULL, NULL,\n\t\t     opt_hidden),\n\tOPT_WITH_ARG(\"--rotate\",\n\t\t     set_rotate, opt_show_intval, &opt_rotate_period,\n\t\t     \"Change multipool strategy from failover to regularly rotate at N minutes\"),\n\tOPT_WITHOUT_ARG(\"--round-robin\",\n\t\t     set_rr, &pool_strategy,\n\t\t     \"Change multipool strategy from failover to round robin on failure\"),\n#ifdef USE_FPGA_SERIAL\n\tOPT_WITH_ARG(\"--scan-serial|-S\",\n\t\t     add_serial, NULL, NULL,\n\t\t     \"Serial port to probe for Icarus FPGA Mining device\"),\n#endif\n\tOPT_WITH_ARG(\"--scan-time|-s\",\n\t\t     set_int_0_to_9999, opt_show_intval, &opt_scantime,\n\t\t     \"Upper bound on time spent scanning current work, in seconds\"),\n\tOPT_WITH_ARG(\"--sched-start\",\n\t\t     set_schedtime, NULL, &schedstart,\n\t\t     \"Set a time of day in HH:MM to start mining (a once off without a stop time)\"),\n\tOPT_WITH_ARG(\"--sched-stop\",\n\t\t     set_schedtime, NULL, &schedstop,\n\t\t     \"Set a time of day in HH:MM to stop mining (will quit without a start time)\"),\n#ifdef USE_SCRYPT\n\tOPT_WITHOUT_ARG(\"--scrypt\",\n\t\t\topt_set_bool, &opt_scrypt,\n\t\t\t\"Use the scrypt algorithm for mining (litecoin only)\"),\n#ifdef HAVE_OPENCL\t\t\t// KRAMBLE\n\tOPT_WITH_ARG(\"--shaders\",\n\t\t     set_shaders, NULL, NULL,\n\t\t     \"GPU shaders per card for tuning scrypt, comma separated\"),\n#endif\n#endif\n\tOPT_WITH_ARG(\"--sharelog\",\n\t\t     set_sharelog, NULL, NULL,\n\t\t     \"Append share log to file\"),\n\tOPT_WITH_ARG(\"--shares\",\n\t\t     opt_set_intval, NULL, &opt_shares,\n\t\t     \"Quit after mining N shares (default: unlimited)\"),\n\tOPT_WITH_ARG(\"--socks-proxy\",\n\t\t     opt_set_charp, NULL, &opt_socks_proxy,\n\t\t     \"Set socks4 proxy (host:port)\"),\n#ifdef HAVE_SYSLOG_H\n\tOPT_WITHOUT_ARG(\"--syslog\",\n\t\t\topt_set_bool, &use_syslog,\n\t\t\t\"Use system log for output messages (default: standard error)\"),\n#endif\n#if defined(HAVE_ADL) || defined(USE_BITFORCE) || defined(USE_MODMINER) || defined(USE_BFLSC)\n\tOPT_WITH_ARG(\"--temp-cutoff\",\n\t\t     set_temp_cutoff, opt_show_intval, &opt_cutofftemp,\n\t\t     \"Temperature where a device will be automatically disabled, one value or comma separated list\"),\n#endif\n#ifdef HAVE_ADL\n\tOPT_WITH_ARG(\"--temp-hysteresis\",\n\t\t     set_int_1_to_10, opt_show_intval, &opt_hysteresis,\n\t\t     \"Set how much the temperature can fluctuate outside limits when automanaging speeds\"),\n\tOPT_WITH_ARG(\"--temp-overheat\",\n\t\t     set_temp_overheat, opt_show_intval, &opt_overheattemp,\n\t\t     \"Overheat temperature when automatically managing fan and GPU speeds, one value or comma separated list\"),\n\tOPT_WITH_ARG(\"--temp-target\",\n\t\t     set_temp_target, opt_show_intval, &opt_targettemp,\n\t\t     \"Target temperature when automatically managing fan and GPU speeds, one value or comma separated list\"),\n#endif\n\tOPT_WITHOUT_ARG(\"--text-only|-T\",\n\t\t\topt_set_invbool, &use_curses,\n#ifdef HAVE_CURSES\n\t\t\t\"Disable ncurses formatted screen output\"\n#else\n\t\t\topt_hidden\n#endif\n\t),\n#ifdef USE_SCRYPT\n#ifdef HAVE_OPENCL\t\t\t// KRAMBLE\n\tOPT_WITH_ARG(\"--thread-concurrency\",\n\t\t     set_thread_concurrency, NULL, NULL,\n\t\t     \"Set GPU thread concurrency for scrypt mining, comma separated\"),\n#endif\n#endif\n\tOPT_WITH_ARG(\"--url|-o\",\n\t\t     set_url, NULL, NULL,\n\t\t     \"URL for bitcoin JSON-RPC server\"),\n\tOPT_WITH_ARG(\"--user|-u\",\n\t\t     set_user, NULL, NULL,\n\t\t     \"Username for bitcoin JSON-RPC server\"),\n#ifdef USE_USBUTILS\n\tOPT_WITH_ARG(\"--usb\",\n\t\t     set_usb_select, NULL, NULL,\n\t\t     \"USB device selection\"),\n\tOPT_WITH_ARG(\"--usb-dump\",\n\t\t     set_int_0_to_10, opt_show_intval, &opt_usbdump,\n\t\t     opt_hidden),\n\tOPT_WITHOUT_ARG(\"--usb-list-all\",\n\t\t\topt_set_bool, &opt_usb_list_all,\n\t\t\topt_hidden),\n#endif\n#ifdef HAVE_OPENCL\n\tOPT_WITH_ARG(\"--vectors|-v\",\n\t\t     set_vector, NULL, NULL,\n\t\t     \"Override detected optimal vector (1, 2 or 4) - one value or comma separated list\"),\n#endif\n\tOPT_WITHOUT_ARG(\"--verbose\",\n\t\t\topt_set_bool, &opt_log_output,\n\t\t\t\"Log verbose output to stderr as well as status output\"),\n#ifdef HAVE_OPENCL\n\tOPT_WITH_ARG(\"--worksize|-w\",\n\t\t     set_worksize, NULL, NULL,\n\t\t     \"Override detected optimal worksize - one value or comma separated list\"),\n#endif\n\tOPT_WITH_ARG(\"--userpass|-O\",\n\t\t     set_userpass, NULL, NULL,\n\t\t     \"Username:Password pair for bitcoin JSON-RPC server\"),\n\tOPT_WITHOUT_ARG(\"--worktime\",\n\t\t\topt_set_bool, &opt_worktime,\n\t\t\t\"Display extra work time debug information\"),\n\tOPT_WITH_ARG(\"--pools\",\n\t\t\topt_set_bool, NULL, NULL, opt_hidden),\n\tOPT_ENDTABLE\n};\n\nstatic char *load_config(const char *arg, void __maybe_unused *unused);\n\nstatic int fileconf_load;\n\nstatic char *parse_config(json_t *config, bool fileconf)\n{\n\tstatic char err_buf[200];\n\tstruct opt_table *opt;\n\tjson_t *val;\n\n\tif (fileconf && !fileconf_load)\n\t\tfileconf_load = 1;\n\n\tfor (opt = opt_config_table; opt->type != OPT_END; opt++) {\n\t\tchar *p, *name;\n\n\t\t/* We don't handle subtables. */\n\t\tassert(!(opt->type & OPT_SUBTABLE));\n\n\t\t/* Pull apart the option name(s). */\n\t\tname = strdup(opt->names);\n\t\tfor (p = strtok(name, \"|\"); p; p = strtok(NULL, \"|\")) {\n\t\t\tchar *err = NULL;\n\n\t\t\t/* Ignore short options. */\n\t\t\tif (p[1] != '-')\n\t\t\t\tcontinue;\n\n\t\t\tval = json_object_get(config, p+2);\n\t\t\tif (!val)\n\t\t\t\tcontinue;\n\n\t\t\tif ((opt->type & OPT_HASARG) && json_is_string(val)) {\n\t\t\t\terr = opt->cb_arg(json_string_value(val),\n\t\t\t\t\t\t  opt->u.arg);\n\t\t\t} else if ((opt->type & OPT_HASARG) && json_is_array(val)) {\n\t\t\t\tint n, size = json_array_size(val);\n\n\t\t\t\tfor (n = 0; n < size && !err; n++) {\n\t\t\t\t\tif (json_is_string(json_array_get(val, n)))\n\t\t\t\t\t\terr = opt->cb_arg(json_string_value(json_array_get(val, n)), opt->u.arg);\n\t\t\t\t\telse if (json_is_object(json_array_get(val, n)))\n\t\t\t\t\t\terr = parse_config(json_array_get(val, n), false);\n\t\t\t\t}\n\t\t\t} else if ((opt->type & OPT_NOARG) && json_is_true(val))\n\t\t\t\terr = opt->cb(opt->u.arg);\n\t\t\telse\n\t\t\t\terr = \"Invalid value\";\n\n\t\t\tif (err) {\n\t\t\t\t/* Allow invalid values to be in configuration\n\t\t\t\t * file, just skipping over them provided the\n\t\t\t\t * JSON is still valid after that. */\n\t\t\t\tif (fileconf) {\n\t\t\t\t\tapplog(LOG_ERR, \"Invalid config option %s: %s\", p, err);\n\t\t\t\t\tfileconf_load = -1;\n\t\t\t\t} else {\n\t\t\t\t\tsprintf(err_buf, \"Parsing JSON option %s: %s\",\n\t\t\t\t\t\tp, err);\n\t\t\t\t\treturn err_buf;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfree(name);\n\t}\n\n\tval = json_object_get(config, JSON_INCLUDE_CONF);\n\tif (val && json_is_string(val))\n\t\treturn load_config(json_string_value(val), NULL);\n\n\treturn NULL;\n}\n\nchar *cnfbuf = NULL;\n\nstatic char *load_config(const char *arg, void __maybe_unused *unused)\n{\n\tjson_error_t err;\n\tjson_t *config;\n\tchar *json_error;\n\n\tif (!cnfbuf)\n\t\tcnfbuf = strdup(arg);\n\n\tif (++include_count > JSON_MAX_DEPTH)\n\t\treturn JSON_MAX_DEPTH_ERR;\n\n#if JANSSON_MAJOR_VERSION > 1\n\tconfig = json_load_file(arg, 0, &err);\n#else\n\tconfig = json_load_file(arg, &err);\n#endif\n\tif (!json_is_object(config)) {\n\t\tjson_error = malloc(JSON_LOAD_ERROR_LEN + strlen(arg) + strlen(err.text));\n\t\tif (!json_error)\n\t\t\tquit(1, \"Malloc failure in json error\");\n\n\t\tsprintf(json_error, JSON_LOAD_ERROR, arg, err.text);\n\t\treturn json_error;\n\t}\n\n\tconfig_loaded = true;\n\n\t/* Parse the config now, so we can override it.  That can keep pointers\n\t * so don't free config object. */\n\treturn parse_config(config, true);\n}\n\nstatic char *set_default_config(const char *arg)\n{\n\topt_set_charp(arg, &default_config);\n\n\treturn NULL;\n}\n\nvoid default_save_file(char *filename);\n\nstatic void load_default_config(void)\n{\n\tcnfbuf = malloc(PATH_MAX);\n\n\tdefault_save_file(cnfbuf);\n\n\tif (!access(cnfbuf, R_OK))\n\t\tload_config(cnfbuf, NULL);\n\telse {\n\t\tfree(cnfbuf);\n\t\tcnfbuf = NULL;\n\t}\n}\n\nextern const char *opt_argv0;\n\nstatic char *opt_verusage_and_exit(const char *extra)\n{\n\tprintf(\"%s\\nBuilt with \"\n#ifdef USE_BFLSC\n\t\t\"bflsc \"\n#endif\n#ifdef HAVE_OPENCL\n\t\t\"GPU \"\n#endif\n#ifdef USE_BITFORCE\n\t\t\"bitforce \"\n#endif\n#ifdef USE_ICARUS\n\t\t\"icarus \"\n#endif\n#ifdef USE_AVALON\n\t\t\"avalon \"\n#endif\n#ifdef USE_MODMINER\n\t\t\"modminer \"\n#endif\n#ifdef USE_ZTEX\n\t\t\"ztex \"\n#endif\n#ifdef USE_SCRYPT\n\t\t\"scrypt \"\n#endif\n\t\t\"mining support.\\n\"\n\t\t, packagename);\n\tprintf(\"%s\", opt_usage(opt_argv0, extra));\n\tfflush(stdout);\n\texit(0);\n}\n\n#if defined(HAVE_OPENCL) || defined(USE_USBUTILS)\nchar *display_devs(int *ndevs)\n{\n\t*ndevs = 0;\n#ifdef HAVE_OPENCL\n\tprint_ndevs(ndevs);\n#endif\n#ifdef USE_USBUTILS\n\tusb_all(0);\n#endif\n\texit(*ndevs);\n}\n#endif\n\n/* These options are available from commandline only */\nstatic struct opt_table opt_cmdline_table[] = {\n\tOPT_WITH_ARG(\"--config|-c\",\n\t\t     load_config, NULL, NULL,\n\t\t     \"Load a JSON-format configuration file\\n\"\n\t\t     \"See example.conf for an example configuration.\"),\n\tOPT_WITH_ARG(\"--default-config\",\n\t\t     set_default_config, NULL, NULL,\n\t\t     \"Specify the filename of the default config file\\n\"\n\t\t     \"Loaded at start and used when saving without a name.\"),\n\tOPT_WITHOUT_ARG(\"--help|-h\",\n\t\t\topt_verusage_and_exit, NULL,\n\t\t\t\"Print this message\"),\n#if defined(HAVE_OPENCL) || defined(USE_USBUTILS)\n\tOPT_WITHOUT_ARG(\"--ndevs|-n\",\n\t\t\tdisplay_devs, &nDevs,\n\t\t\t\"Display \"\n#ifdef HAVE_OPENCL\n\t\t\t\"number of detected GPUs, OpenCL platform information, \"\n#endif\n#ifdef USE_USBUTILS\n\t\t\t\"all USB devices, \"\n#endif\n\t\t\t\"and exit\"),\n#endif\n\tOPT_WITHOUT_ARG(\"--version|-V\",\n\t\t\topt_version_and_exit, packagename,\n\t\t\t\"Display version and exit\"),\n\tOPT_ENDTABLE\n};\n\nstatic bool jobj_binary(const json_t *obj, const char *key,\n\t\t\tvoid *buf, size_t buflen, bool required)\n{\n\tconst char *hexstr;\n\tjson_t *tmp;\n\n\ttmp = json_object_get(obj, key);\n\tif (unlikely(!tmp)) {\n\t\tif (unlikely(required))\n\t\t\tapplog(LOG_ERR, \"JSON key '%s' not found\", key);\n\t\treturn false;\n\t}\n\thexstr = json_string_value(tmp);\n\tif (unlikely(!hexstr)) {\n\t\tapplog(LOG_ERR, \"JSON key '%s' is not a string\", key);\n\t\treturn false;\n\t}\n\tif (!hex2bin(buf, hexstr, buflen))\n\t\treturn false;\n\n\treturn true;\n}\n\n// Moved from driver_ztex.c for scrypt\nuint32_t ztex_checkNonce(struct work *work, uint32_t nonce)\n{\n\tstruct work *tmpwork = (struct work *)malloc(sizeof(struct work));\n\tmemcpy(tmpwork, work, sizeof(struct work));\n\n\tuint32_t *work_nonce = (uint32_t *)(tmpwork->data + 64 + 12);\n\t*work_nonce = htole32(nonce);\n\t\n\tscrypt_regenhash(tmpwork);\n\n\tunsigned char hash2[32];\n\tuint32_t *hash2_32 = (uint32_t *)hash2;\n\tflip32(hash2_32, tmpwork->hash);\n\n\t// applog(LOG_WARNING, \"nonce %08x hash0 %08x hash7 %08x\", nonce, hash2_32[0], hash2_32[7]);\t// KRAMBLE\n\n\tfree (tmpwork);\n\treturn hash2_32[7];\n}\n\nstatic void calc_midstate(struct work *work)\n{\n\tunsigned char data[64];\n\tuint32_t *data32 = (uint32_t *)data;\n\tsha2_context ctx;\n\n\tflip64(data32, work->data);\n\tsha2_starts(&ctx);\n\tsha2_update(&ctx, data, 64);\n\tmemcpy(work->midstate, ctx.state, 32);\n\tendian_flip32(work->midstate, work->midstate);\n}\n\nstatic struct work *make_work(void)\n{\n\tstruct work *work = calloc(1, sizeof(struct work));\n\n\tif (unlikely(!work))\n\t\tquit(1, \"Failed to calloc work in make_work\");\n\n\tcg_wlock(&control_lock);\n\twork->id = total_work++;\n\tcg_wunlock(&control_lock);\n\n\treturn work;\n}\n\n/* This is the central place all work that is about to be retired should be\n * cleaned to remove any dynamically allocated arrays within the struct */\nvoid clean_work(struct work *work)\n{\n\tfree(work->job_id);\n\tfree(work->nonce2);\n\tfree(work->ntime);\n\tfree(work->gbt_coinbase);\n\tfree(work->nonce1);\n\tmemset(work, 0, sizeof(struct work));\n}\n\n/* All dynamically allocated work structs should be freed here to not leak any\n * ram from arrays allocated within the work struct */\nvoid free_work(struct work *work)\n{\n\tclean_work(work);\n\tfree(work);\n}\n\n/* Generate a GBT coinbase from the existing GBT variables stored. Must be\n * entered under gbt_lock */\nstatic void __build_gbt_coinbase(struct pool *pool)\n{\n\tunsigned char *coinbase;\n\tint cbt_len, orig_len;\n\tuint8_t *extra_len;\n\tsize_t cal_len;\n\n\tcbt_len = strlen(pool->coinbasetxn) / 2;\n\tpool->coinbase_len = cbt_len + 4;\n\t/* We add 4 bytes of extra data corresponding to nonce2 of stratum */\n\tcal_len = pool->coinbase_len + 1;\n\talign_len(&cal_len);\n\tcoinbase = calloc(cal_len, 1);\n\thex2bin(coinbase, pool->coinbasetxn, 42);\n\textra_len = (uint8_t *)(coinbase + 41);\n\torig_len = *extra_len;\n\thex2bin(coinbase + 42, pool->coinbasetxn + 84, orig_len);\n\tmemcpy(coinbase + 42 + orig_len, &pool->nonce2, 4);\n\t*extra_len += 4;\n\thex2bin(coinbase + 42 + *extra_len, pool->coinbasetxn + 84 + (orig_len * 2), cbt_len - orig_len - 42);\n\tpool->nonce2++;\n\tfree(pool->gbt_coinbase);\n\tpool->gbt_coinbase = coinbase;\n}\n\nstatic void gen_hash(unsigned char *data, unsigned char *hash, int len);\n\n/* Process transactions with GBT by storing the binary value of the first\n * transaction, and the hashes of the remaining transactions since these\n * remain constant with an altered coinbase when generating work. Must be\n * entered under gbt_lock */\nstatic bool __build_gbt_txns(struct pool *pool, json_t *res_val)\n{\n\tjson_t *txn_array;\n\tbool ret = false;\n\tsize_t cal_len;\n\tint i;\n\n\tfree(pool->txn_hashes);\n\tpool->txn_hashes = NULL;\n\tpool->gbt_txns = 0;\n\n\ttxn_array = json_object_get(res_val, \"transactions\");\n\tif (!json_is_array(txn_array))\n\t\tgoto out;\n\n\tret = true;\n\tpool->gbt_txns = json_array_size(txn_array);\n\tif (!pool->gbt_txns)\n\t\tgoto out;\n\n\tpool->txn_hashes = calloc(32 * (pool->gbt_txns + 1), 1);\n\tif (unlikely(!pool->txn_hashes))\n\t\tquit(1, \"Failed to calloc txn_hashes in __build_gbt_txns\");\n\n\tfor (i = 0; i < pool->gbt_txns; i++) {\n\t\tjson_t *txn_val = json_object_get(json_array_get(txn_array, i), \"data\");\n\t\tconst char *txn = json_string_value(txn_val);\n\t\tint txn_len = strlen(txn);\n\t\tunsigned char *txn_bin;\n\n\t\tcal_len = txn_len;\n\t\talign_len(&cal_len);\n\t\ttxn_bin = calloc(cal_len, 1);\n\t\tif (unlikely(!txn_bin))\n\t\t\tquit(1, \"Failed to calloc txn_bin in __build_gbt_txns\");\n\t\tif (unlikely(!hex2bin(txn_bin, txn, txn_len / 2)))\n\t\t\tquit(1, \"Failed to hex2bin txn_bin\");\n\n\t\tgen_hash(txn_bin, pool->txn_hashes + (32 * i), txn_len / 2);\n\t\tfree(txn_bin);\n\t}\nout:\n\treturn ret;\n}\n\nstatic unsigned char *__gbt_merkleroot(struct pool *pool)\n{\n\tunsigned char *merkle_hash;\n\tint i, txns;\n\n\tmerkle_hash = calloc(32 * (pool->gbt_txns + 2), 1);\n\tif (unlikely(!merkle_hash))\n\t\tquit(1, \"Failed to calloc merkle_hash in __gbt_merkleroot\");\n\n\tgen_hash(pool->gbt_coinbase, merkle_hash, pool->coinbase_len);\n\n\tif (pool->gbt_txns)\n\t\tmemcpy(merkle_hash + 32, pool->txn_hashes, pool->gbt_txns * 32);\n\n\ttxns = pool->gbt_txns + 1;\n\twhile (txns > 1) {\n\t\tif (txns % 2) {\n\t\t\tmemcpy(&merkle_hash[txns * 32], &merkle_hash[(txns - 1) * 32], 32);\n\t\t\ttxns++;\n\t\t}\n\t\tfor (i = 0; i < txns; i += 2){\n\t\t\tunsigned char hashout[32];\n\n\t\t\tgen_hash(merkle_hash + (i * 32), hashout, 64);\n\t\t\tmemcpy(merkle_hash + (i / 2 * 32), hashout, 32);\n\t\t}\n\t\ttxns /= 2;\n\t}\n\treturn merkle_hash;\n}\n\nstatic void calc_diff(struct work *work, int known);\nstatic bool work_decode(struct pool *pool, struct work *work, json_t *val);\n\nstatic void update_gbt(struct pool *pool)\n{\n\tint rolltime;\n\tjson_t *val;\n\tCURL *curl;\n\n\tcurl = curl_easy_init();\n\tif (unlikely(!curl))\n\t\tquit (1, \"CURL initialisation failed in update_gbt\");\n\n\tval = json_rpc_call(curl, pool->rpc_url, pool->rpc_userpass,\n\t\t\t    pool->rpc_req, true, false, &rolltime, pool, false);\n\n\tif (val) {\n\t\tstruct work *work = make_work();\n\t\tbool rc = work_decode(pool, work, val);\n\n\t\ttotal_getworks++;\n\t\tpool->getwork_requested++;\n\t\tif (rc) {\n\t\t\tapplog(LOG_DEBUG, \"Successfully retrieved and updated GBT from pool %u %s\",\n\t\t\t       pool->pool_no, pool->rpc_url);\n\t\t\tcgtime(&pool->tv_idle);\n\t\t} else {\n\t\t\tapplog(LOG_DEBUG, \"Successfully retrieved but FAILED to decipher GBT from pool %u %s\",\n\t\t\t       pool->pool_no, pool->rpc_url);\n\t\t}\n\t\tjson_decref(val);\n\t\tfree_work(work);\n\t} else {\n\t\tapplog(LOG_DEBUG, \"FAILED to update GBT from pool %u %s\",\n\t\t       pool->pool_no, pool->rpc_url);\n\t}\n\tcurl_easy_cleanup(curl);\n}\n\nstatic char *workpadding = \"000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\";\n\nstatic void gen_gbt_work(struct pool *pool, struct work *work)\n{\n\tunsigned char *merkleroot;\n\tstruct timeval now;\n\n\tcgtime(&now);\n\tif (now.tv_sec - pool->tv_lastwork.tv_sec > 60)\n\t\tupdate_gbt(pool);\n\n\tcg_ilock(&pool->gbt_lock);\n\t__build_gbt_coinbase(pool);\n\tcg_dlock(&pool->gbt_lock);\n\tmerkleroot = __gbt_merkleroot(pool);\n\n\tmemcpy(work->data, &pool->gbt_version, 4);\n\tmemcpy(work->data + 4, pool->previousblockhash, 32);\n\tmemcpy(work->data + 4 + 32 + 32, &pool->curtime, 4);\n\tmemcpy(work->data + 4 + 32 + 32 + 4, &pool->gbt_bits, 4);\n\n\tmemcpy(work->target, pool->gbt_target, 32);\n\n\twork->gbt_coinbase = bin2hex(pool->gbt_coinbase, pool->coinbase_len);\n\n\t/* For encoding the block data on submission */\n\twork->gbt_txns = pool->gbt_txns + 1;\n\n\tif (pool->gbt_workid)\n\t\twork->job_id = strdup(pool->gbt_workid);\n\tcg_runlock(&pool->gbt_lock);\n\n\tmemcpy(work->data + 4 + 32, merkleroot, 32);\n\tflip32(work->data + 4 + 32, merkleroot);\n\tfree(merkleroot);\n\tmemset(work->data + 4 + 32 + 32 + 4 + 4, 0, 4); /* nonce */\n\n\thex2bin(work->data + 4 + 32 + 32 + 4 + 4 + 4, workpadding, 48);\n\n\tif (opt_debug) {\n\t\tchar *header = bin2hex(work->data, 128);\n\n\t\tapplog(LOG_DEBUG, \"Generated GBT header %s\", header);\n\t\tapplog(LOG_DEBUG, \"Work coinbase %s\", work->gbt_coinbase);\n\t\tfree(header);\n\t}\n\n\tcalc_midstate(work);\n\tlocal_work++;\n\twork->pool = pool;\n\twork->gbt = true;\n\twork->id = total_work++;\n\twork->longpoll = false;\n\twork->getwork_mode = GETWORK_MODE_GBT;\n\twork->work_block = work_block;\n\tcalc_diff(work, 0);\n\tcgtime(&work->tv_staged);\n}\n\nstatic bool gbt_decode(struct pool *pool, json_t *res_val)\n{\n\tconst char *previousblockhash;\n\tconst char *target;\n\tconst char *coinbasetxn;\n\tconst char *longpollid;\n\tunsigned char hash_swap[32];\n\tint expires;\n\tint version;\n\tint curtime;\n\tbool submitold;\n\tconst char *bits;\n\tconst char *workid;\n\n\tpreviousblockhash = json_string_value(json_object_get(res_val, \"previousblockhash\"));\n\ttarget = json_string_value(json_object_get(res_val, \"target\"));\n\tcoinbasetxn = json_string_value(json_object_get(json_object_get(res_val, \"coinbasetxn\"), \"data\"));\n\tlongpollid = json_string_value(json_object_get(res_val, \"longpollid\"));\n\texpires = json_integer_value(json_object_get(res_val, \"expires\"));\n\tversion = json_integer_value(json_object_get(res_val, \"version\"));\n\tcurtime = json_integer_value(json_object_get(res_val, \"curtime\"));\n\tsubmitold = json_is_true(json_object_get(res_val, \"submitold\"));\n\tbits = json_string_value(json_object_get(res_val, \"bits\"));\n\tworkid = json_string_value(json_object_get(res_val, \"workid\"));\n\n\tif (!previousblockhash || !target || !coinbasetxn || !longpollid ||\n\t    !expires || !version || !curtime || !bits) {\n\t\tapplog(LOG_ERR, \"JSON failed to decode GBT\");\n\t\treturn false;\n\t}\n\n\tapplog(LOG_DEBUG, \"previousblockhash: %s\", previousblockhash);\n\tapplog(LOG_DEBUG, \"target: %s\", target);\n\tapplog(LOG_DEBUG, \"coinbasetxn: %s\", coinbasetxn);\n\tapplog(LOG_DEBUG, \"longpollid: %s\", longpollid);\n\tapplog(LOG_DEBUG, \"expires: %d\", expires);\n\tapplog(LOG_DEBUG, \"version: %d\", version);\n\tapplog(LOG_DEBUG, \"curtime: %d\", curtime);\n\tapplog(LOG_DEBUG, \"submitold: %s\", submitold ? \"true\" : \"false\");\n\tapplog(LOG_DEBUG, \"bits: %s\", bits);\n\tif (workid)\n\t\tapplog(LOG_DEBUG, \"workid: %s\", workid);\n\n\tcg_wlock(&pool->gbt_lock);\n\tfree(pool->coinbasetxn);\n\tpool->coinbasetxn = strdup(coinbasetxn);\n\tfree(pool->longpollid);\n\tpool->longpollid = strdup(longpollid);\n\tfree(pool->gbt_workid);\n\tif (workid)\n\t\tpool->gbt_workid = strdup(workid);\n\telse\n\t\tpool->gbt_workid = NULL;\n\n\thex2bin(hash_swap, previousblockhash, 32);\n\tswap256(pool->previousblockhash, hash_swap);\n\n\thex2bin(hash_swap, target, 32);\n\tswab256(pool->gbt_target, hash_swap);\n\n\tpool->gbt_expires = expires;\n\tpool->gbt_version = htobe32(version);\n\tpool->curtime = htobe32(curtime);\n\tpool->submit_old = submitold;\n\n\thex2bin((unsigned char *)&pool->gbt_bits, bits, 4);\n\n\t__build_gbt_txns(pool, res_val);\n\tcg_wunlock(&pool->gbt_lock);\n\n\treturn true;\n}\n\nstatic bool getwork_decode(json_t *res_val, struct work *work)\n{\n\tif (unlikely(!jobj_binary(res_val, \"data\", work->data, sizeof(work->data), true))) {\n\t\tapplog(LOG_ERR, \"JSON inval data\");\n\t\treturn false;\n\t}\n\n\tif (!jobj_binary(res_val, \"midstate\", work->midstate, sizeof(work->midstate), false)) {\n\t\t// Calculate it ourselves\n\t\tapplog(LOG_DEBUG, \"Calculating midstate locally\");\n\t\tcalc_midstate(work);\n\t}\n\n\tif (unlikely(!jobj_binary(res_val, \"target\", work->target, sizeof(work->target), true))) {\n\t\tapplog(LOG_ERR, \"JSON inval target\");\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nstatic bool work_decode(struct pool *pool, struct work *work, json_t *val)\n{\n\tjson_t *res_val = json_object_get(val, \"result\");\n\tbool ret = false;\n\n\tcgtime(&pool->tv_lastwork);\n\tif (!res_val || json_is_null(res_val)) {\n\t\tapplog(LOG_ERR, \"JSON Failed to decode result\");\n\t\tgoto out;\n\t}\n\n\tif (pool->has_gbt) {\n\t\tif (unlikely(!gbt_decode(pool, res_val)))\n\t\t\tgoto out;\n\t\twork->gbt = true;\n\t\tret = true;\n\t\tgoto out;\n\t} else if (unlikely(!getwork_decode(res_val, work)))\n\t\tgoto out;\n\n\tmemset(work->hash, 0, sizeof(work->hash));\n\n\tcgtime(&work->tv_staged);\n\n\tret = true;\n\nout:\n\treturn ret;\n}\n\nint dev_from_id(int thr_id)\n{\n\tstruct cgpu_info *cgpu = get_thr_cgpu(thr_id);\n\n\treturn cgpu->device_id;\n}\n\n/* Make the change in the recent value adjust dynamically when the difference\n * is large, but damp it when the values are closer together. This allows the\n * value to change quickly, but not fluctuate too dramatically when it has\n * stabilised. */\nvoid decay_time(double *f, double fadd)\n{\n\tdouble ratio = 0;\n\n\tif (likely(*f > 0)) {\n\t\tratio = fadd / *f;\n\t\tif (ratio > 1)\n\t\t\tratio = 1 / ratio;\n\t}\n\n\tif (ratio > 0.63)\n\t\t*f = (fadd * 0.58 + *f) / 1.58;\n\telse\n\t\t*f = (fadd + *f * 0.58) / 1.58;\n}\n\nstatic int __total_staged(void)\n{\n\treturn HASH_COUNT(staged_work);\n}\n\nstatic int total_staged(void)\n{\n\tint ret;\n\n\tmutex_lock(stgd_lock);\n\tret = __total_staged();\n\tmutex_unlock(stgd_lock);\n\n\treturn ret;\n}\n\n#ifdef HAVE_CURSES\nWINDOW *mainwin, *statuswin, *logwin;\n#endif\ndouble total_secs = 1.0;\nstatic char statusline[256];\n/* logstart is where the log window should start */\nstatic int devcursor, logstart, logcursor;\n#ifdef HAVE_CURSES\n/* statusy is where the status window goes up to in cases where it won't fit at startup */\nstatic int statusy;\n#endif\n#ifdef HAVE_OPENCL\nstruct cgpu_info gpus[MAX_GPUDEVICES]; /* Maximum number apparently possible */\n#endif\n\n#ifdef HAVE_CURSES\nstatic inline void unlock_curses(void)\n{\n\tmutex_unlock(&console_lock);\n}\n\nstatic inline void lock_curses(void)\n{\n\tmutex_lock(&console_lock);\n}\n\nstatic bool curses_active_locked(void)\n{\n\tbool ret;\n\n\tlock_curses();\n\tret = curses_active;\n\tif (!ret)\n\t\tunlock_curses();\n\treturn ret;\n}\n#endif\n\nvoid tailsprintf(char *f, const char *fmt, ...)\n{\n\tva_list ap;\n\n\tva_start(ap, fmt);\n\tvsprintf(f + strlen(f), fmt, ap);\n\tva_end(ap);\n}\n\n/* Convert a uint64_t value into a truncated string for displaying with its\n * associated suitable for Mega, Giga etc. Buf array needs to be long enough */\nstatic void suffix_string(uint64_t val, char *buf, int sigdigits)\n{\n\tconst double  dkilo = 1000.0;\n\tconst uint64_t kilo = 1000ull;\n\tconst uint64_t mega = 1000000ull;\n\tconst uint64_t giga = 1000000000ull;\n\tconst uint64_t tera = 1000000000000ull;\n\tconst uint64_t peta = 1000000000000000ull;\n\tconst uint64_t exa  = 1000000000000000000ull;\n\tchar suffix[2] = \"\";\n\tbool decimal = true;\n\tdouble dval;\n\n\tif (val >= exa) {\n\t\tval /= peta;\n\t\tdval = (double)val / dkilo;\n\t\tsprintf(suffix, \"E\");\n\t} else if (val >= peta) {\n\t\tval /= tera;\n\t\tdval = (double)val / dkilo;\n\t\tsprintf(suffix, \"P\");\n\t} else if (val >= tera) {\n\t\tval /= giga;\n\t\tdval = (double)val / dkilo;\n\t\tsprintf(suffix, \"T\");\n\t} else if (val >= giga) {\n\t\tval /= mega;\n\t\tdval = (double)val / dkilo;\n\t\tsprintf(suffix, \"G\");\n\t} else if (val >= mega) {\n\t\tval /= kilo;\n\t\tdval = (double)val / dkilo;\n\t\tsprintf(suffix, \"M\");\n\t} else if (val >= kilo) {\n\t\tdval = (double)val / dkilo;\n\t\tsprintf(suffix, \"K\");\n\t} else {\n\t\tdval = val;\n\t\tdecimal = false;\n\t}\n\n\tif (!sigdigits) {\n\t\tif (decimal)\n\t\t\tsprintf(buf, \"%.3g%s\", dval, suffix);\n\t\telse\n\t\t\tsprintf(buf, \"%d%s\", (unsigned int)dval, suffix);\n\t} else {\n\t\t/* Always show sigdigits + 1, padded on right with zeroes\n\t\t * followed by suffix */\n\t\tint ndigits = sigdigits - 1 - (dval > 0.0 ? floor(log10(dval)) : 0);\n\n\t\tsprintf(buf, \"%*.*f%s\", sigdigits + 1, ndigits, dval, suffix);\n\t}\n}\n\nstatic void get_statline(char *buf, struct cgpu_info *cgpu)\n{\n\tchar displayed_hashes[16], displayed_rolling[16];\n\tuint64_t dh64, dr64;\n\n\tdh64 = (double)cgpu->total_mhashes / total_secs * 1000000ull;\n\tdr64 = (double)cgpu->rolling * 1000000ull;\n\tsuffix_string(dh64, displayed_hashes, 4);\n\tsuffix_string(dr64, displayed_rolling, 4);\n\n\tsprintf(buf, \"%s%d \", cgpu->drv->name, cgpu->device_id);\n\tcgpu->drv->get_statline_before(buf, cgpu);\n\ttailsprintf(buf, \"(%ds):%s (avg):%sh/s | A:%d R:%d HW:%d U:%.1f/m\",\n\t\topt_log_interval,\n\t\tdisplayed_rolling,\n\t\tdisplayed_hashes,\n\t\tcgpu->accepted,\n\t\tcgpu->rejected,\n\t\tcgpu->hw_errors,\n\t\tcgpu->utility);\n\tcgpu->drv->get_statline(buf, cgpu);\n}\n\nstatic void text_print_status(int thr_id)\n{\n\tstruct cgpu_info *cgpu;\n\tchar logline[256];\n\n\tcgpu = get_thr_cgpu(thr_id);\n\tif (cgpu) {\n\t\tget_statline(logline, cgpu);\n\t\tprintf(\"%s\\n\", logline);\n\t}\n}\n\n#ifdef HAVE_CURSES\n/* Must be called with curses mutex lock held and curses_active */\nstatic void curses_print_status(void)\n{\n\tstruct pool *pool = current_pool();\n\n\twattron(statuswin, A_BOLD);\n\tmvwprintw(statuswin, 0, 0, \" \" PACKAGE \" version \" VERSION \" - Started: %s\", datestamp);\n\twattroff(statuswin, A_BOLD);\n\tmvwhline(statuswin, 1, 0, '-', 80);\n\tmvwprintw(statuswin, 2, 0, \" %s\", statusline);\n\twclrtoeol(statuswin);\n\tmvwprintw(statuswin, 3, 0, \" ST: %d  SS: %d  NB: %d  LW: %d  GF: %d  RF: %d\",\n\t\ttotal_staged(), total_stale, new_blocks,\n\t\tlocal_work, total_go, total_ro);\n\twclrtoeol(statuswin);\n\tif ((pool_strategy == POOL_LOADBALANCE  || pool_strategy == POOL_BALANCE) && total_pools > 1) {\n\t\tmvwprintw(statuswin, 4, 0, \" Connected to multiple pools with%s LP\",\n\t\t\thave_longpoll ? \"\": \"out\");\n\t} else if (pool->has_stratum) {\n\t\tmvwprintw(statuswin, 4, 0, \" Connected to %s diff %s with stratum as user %s\",\n\t\t\tpool->sockaddr_url, pool->diff, pool->rpc_user);\n\t} else {\n\t\tmvwprintw(statuswin, 4, 0, \" Connected to %s diff %s with%s %s as user %s\",\n\t\t\tpool->sockaddr_url, pool->diff, have_longpoll ? \"\": \"out\",\n\t\t\tpool->has_gbt ? \"GBT\" : \"LP\", pool->rpc_user);\n\t}\n\twclrtoeol(statuswin);\n\tmvwprintw(statuswin, 5, 0, \" Block: %s...  Diff:%s  Started: %s  Best share: %s   \",\n\t\t  current_hash, block_diff, blocktime, best_share);\n\tmvwhline(statuswin, 6, 0, '-', 80);\n\tmvwhline(statuswin, statusy - 1, 0, '-', 80);\n\tmvwprintw(statuswin, devcursor - 1, 1, \"[P]ool management %s[S]ettings [D]isplay options [Q]uit\",\n\t\thave_opencl ? \"[G]PU management \" : \"\");\n}\n\nstatic void adj_width(int var, int *length)\n{\n\tif ((int)(log10(var) + 1) > *length)\n\t\t(*length)++;\n}\n\nstatic int dev_width;\n\nstatic void curses_print_devstatus(int thr_id)\n{\n\tstatic int awidth = 1, rwidth = 1, hwwidth = 1, uwidth = 1;\n\tstruct cgpu_info *cgpu;\n\tchar logline[256];\n\tchar displayed_hashes[16], displayed_rolling[16];\n\tuint64_t dh64, dr64;\n\n\tif (opt_compact)\n\t\treturn;\n\n\tcgpu = get_thr_cgpu(thr_id);\n\n\tif (cgpu->cgminer_id >= start_devices || devcursor + cgpu->cgminer_id > LINES - 2)\n\t\treturn;\n\n\tcgpu->utility = cgpu->accepted / total_secs * 60;\n\n\twmove(statuswin,devcursor + cgpu->cgminer_id, 0);\n\twprintw(statuswin, \" %s %*d: \", cgpu->drv->name, dev_width, cgpu->device_id);\n\tlogline[0] = '\\0';\n\tcgpu->drv->get_statline_before(logline, cgpu);\n\twprintw(statuswin, \"%s\", logline);\n\n\tdh64 = (double)cgpu->total_mhashes / total_secs * 1000000ull;\n\tdr64 = (double)cgpu->rolling * 1000000ull;\n\tsuffix_string(dh64, displayed_hashes, 4);\n\tsuffix_string(dr64, displayed_rolling, 4);\n\n#ifdef USE_USBUTILS\n\tif (cgpu->usbinfo.nodev)\n\t\twprintw(statuswin, \"ZOMBIE\");\n\telse\n#endif\n\tif (cgpu->status == LIFE_DEAD)\n\t\twprintw(statuswin, \"DEAD  \");\n\telse if (cgpu->status == LIFE_SICK)\n\t\twprintw(statuswin, \"SICK  \");\n\telse if (cgpu->deven == DEV_DISABLED)\n\t\twprintw(statuswin, \"OFF   \");\n\telse if (cgpu->deven == DEV_RECOVER)\n\t\twprintw(statuswin, \"REST  \");\n\telse\n\t\twprintw(statuswin, \"%6s\", displayed_rolling);\n\tadj_width(cgpu->accepted, &awidth);\n\tadj_width(cgpu->rejected, &rwidth);\n\tadj_width(cgpu->hw_errors, &hwwidth);\n\tadj_width(cgpu->utility, &uwidth);\n\n\twprintw(statuswin, \"/%6sh/s | A:%*d R:%*d HW:%*d U:%*.2f/m\",\n\t\t\tdisplayed_hashes,\n\t\t\tawidth, cgpu->accepted,\n\t\t\trwidth, cgpu->rejected,\n\t\t\thwwidth, cgpu->hw_errors,\n\t\tuwidth + 3, cgpu->utility);\n\n\tlogline[0] = '\\0';\n\tcgpu->drv->get_statline(logline, cgpu);\n\twprintw(statuswin, \"%s\", logline);\n\n\twclrtoeol(statuswin);\n}\n#endif\n\nstatic void print_status(int thr_id)\n{\n\tif (!curses_active)\n\t\ttext_print_status(thr_id);\n}\n\n#ifdef HAVE_CURSES\n/* Check for window resize. Called with curses mutex locked */\nstatic inline void change_logwinsize(void)\n{\n\tint x, y, logx, logy;\n\n\tgetmaxyx(mainwin, y, x);\n\tif (x < 80 || y < 25)\n\t\treturn;\n\n\tif (y > statusy + 2 && statusy < logstart) {\n\t\tif (y - 2 < logstart)\n\t\t\tstatusy = y - 2;\n\t\telse\n\t\t\tstatusy = logstart;\n\t\tlogcursor = statusy + 1;\n\t\tmvwin(logwin, logcursor, 0);\n\t\twresize(statuswin, statusy, x);\n\t}\n\n\ty -= logcursor;\n\tgetmaxyx(logwin, logy, logx);\n\t/* Detect screen size change */\n\tif (x != logx || y != logy)\n\t\twresize(logwin, y, x);\n}\n\nstatic void check_winsizes(void)\n{\n\tif (!use_curses)\n\t\treturn;\n\tif (curses_active_locked()) {\n\t\tint y, x;\n\n\t\terase();\n\t\tx = getmaxx(statuswin);\n\t\tif (logstart > LINES - 2)\n\t\t\tstatusy = LINES - 2;\n\t\telse\n\t\t\tstatusy = logstart;\n\t\tlogcursor = statusy + 1;\n\t\twresize(statuswin, statusy, x);\n\t\tgetmaxyx(mainwin, y, x);\n\t\ty -= logcursor;\n\t\twresize(logwin, y, x);\n\t\tmvwin(logwin, logcursor, 0);\n\t\tunlock_curses();\n\t}\n}\n\nstatic void switch_compact(void)\n{\n\tif (opt_compact) {\n\t\tlogstart = devcursor + 1;\n\t\tlogcursor = logstart + 1;\n\t} else {\n\t\tlogstart = devcursor + total_devices + 1;\n\t\tlogcursor = logstart + 1;\n\t}\n\tcheck_winsizes();\n}\n\n/* For mandatory printing when mutex is already locked */\nvoid wlog(const char *f, ...)\n{\n\tva_list ap;\n\n\tva_start(ap, f);\n\tvw_printw(logwin, f, ap);\n\tva_end(ap);\n}\n\n/* Mandatory printing */\nvoid wlogprint(const char *f, ...)\n{\n\tva_list ap;\n\n\tif (curses_active_locked()) {\n\t\tva_start(ap, f);\n\t\tvw_printw(logwin, f, ap);\n\t\tva_end(ap);\n\t\tunlock_curses();\n\t}\n}\n#endif\n\n#ifdef HAVE_CURSES\nbool log_curses_only(int prio, const char *f, va_list ap)\n{\n\tbool high_prio;\n\n\thigh_prio = (prio == LOG_WARNING || prio == LOG_ERR);\n\n\tif (curses_active_locked()) {\n\t\tif (!opt_loginput || high_prio) {\n\t\t\tvw_printw(logwin, f, ap);\n\t\t\tif (high_prio) {\n\t\t\t\ttouchwin(logwin);\n\t\t\t\twrefresh(logwin);\n\t\t\t}\n\t\t}\n\t\tunlock_curses();\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nvoid clear_logwin(void)\n{\n\tif (curses_active_locked()) {\n\t\terase();\n\t\twclear(logwin);\n\t\tunlock_curses();\n\t}\n}\n#endif\n\nstatic void enable_pool(struct pool *pool)\n{\n\tif (pool->enabled != POOL_ENABLED) {\n\t\tenabled_pools++;\n\t\tpool->enabled = POOL_ENABLED;\n\t}\n}\n\n#ifdef HAVE_CURSES\nstatic void disable_pool(struct pool *pool)\n{\n\tif (pool->enabled == POOL_ENABLED)\n\t\tenabled_pools--;\n\tpool->enabled = POOL_DISABLED;\n}\n#endif\n\nstatic void reject_pool(struct pool *pool)\n{\n\tif (pool->enabled == POOL_ENABLED)\n\t\tenabled_pools--;\n\tpool->enabled = POOL_REJECTING;\n}\n\nstatic void restart_threads(void);\n\n/* Theoretically threads could race when modifying accepted and\n * rejected values but the chance of two submits completing at the\n * same time is zero so there is no point adding extra locking */\nstatic void\nshare_result(json_t *val, json_t *res, json_t *err, const struct work *work,\n\t     char *hashshow, bool resubmit, char *worktime)\n{\n\tstruct pool *pool = work->pool;\n\tstruct cgpu_info *cgpu;\n\n\tcgpu = get_thr_cgpu(work->thr_id);\n\n\tif (json_is_true(res) || (work->gbt && json_is_null(res))) {\n\t\tmutex_lock(&stats_lock);\n\t\tcgpu->accepted++;\n\t\ttotal_accepted++;\n\t\tpool->accepted++;\n\t\tcgpu->diff_accepted += work->work_difficulty;\n\t\ttotal_diff_accepted += work->work_difficulty;\n\t\tpool->diff_accepted += work->work_difficulty;\n\t\tmutex_unlock(&stats_lock);\n\n\t\tpool->seq_rejects = 0;\n\t\tcgpu->last_share_pool = pool->pool_no;\n\t\tcgpu->last_share_pool_time = time(NULL);\n\t\tcgpu->last_share_diff = work->work_difficulty;\n\t\tpool->last_share_time = cgpu->last_share_pool_time;\n\t\tpool->last_share_diff = work->work_difficulty;\n\t\tapplog(LOG_DEBUG, \"PROOF OF WORK RESULT: true (yay!!!)\");\n\t\tif (!QUIET) {\n\t\t\tif (total_pools > 1)\n\t\t\t\tapplog(LOG_NOTICE, \"Accepted %s %s %d pool %d %s%s\",\n\t\t\t\t       hashshow, cgpu->drv->name, cgpu->device_id, work->pool->pool_no, resubmit ? \"(resubmit)\" : \"\", worktime);\n\t\t\telse\n\t\t\t\tapplog(LOG_NOTICE, \"Accepted %s %s %d %s%s\",\n\t\t\t\t       hashshow, cgpu->drv->name, cgpu->device_id, resubmit ? \"(resubmit)\" : \"\", worktime);\n\t\t}\n\t\tsharelog(\"accept\", work);\n\t\tif (opt_shares && total_accepted >= opt_shares) {\n\t\t\tapplog(LOG_WARNING, \"Successfully mined %d accepted shares as requested and exiting.\", opt_shares);\n\t\t\tkill_work();\n\t\t\treturn;\n\t\t}\n\n\t\t/* Detect if a pool that has been temporarily disabled for\n\t\t * continually rejecting shares has started accepting shares.\n\t\t * This will only happen with the work returned from a\n\t\t * longpoll */\n\t\tif (unlikely(pool->enabled == POOL_REJECTING)) {\n\t\t\tapplog(LOG_WARNING, \"Rejecting pool %d now accepting shares, re-enabling!\", pool->pool_no);\n\t\t\tenable_pool(pool);\n\t\t\tswitch_pools(NULL);\n\t\t}\n\t\t/* If we know we found the block we know better than anyone\n\t\t * that new work is needed. */\n\t\tif (unlikely(work->block))\n\t\t\trestart_threads();\n\t} else {\n\t\tmutex_lock(&stats_lock);\n\t\tcgpu->rejected++;\n\t\ttotal_rejected++;\n\t\tpool->rejected++;\n\t\tcgpu->diff_rejected += work->work_difficulty;\n\t\ttotal_diff_rejected += work->work_difficulty;\n\t\tpool->diff_rejected += work->work_difficulty;\n\t\tpool->seq_rejects++;\n\t\tmutex_unlock(&stats_lock);\n\n\t\tapplog(LOG_DEBUG, \"PROOF OF WORK RESULT: false (booooo)\");\n\t\tif (!QUIET) {\n\t\t\tchar where[20];\n\t\t\tchar disposition[36] = \"reject\";\n\t\t\tchar reason[32];\n\n\t\t\tstrcpy(reason, \"\");\n\t\t\tif (total_pools > 1)\n\t\t\t\tsprintf(where, \"pool %d\", work->pool->pool_no);\n\t\t\telse\n\t\t\t\tstrcpy(where, \"\");\n\n\t\t\tif (!work->gbt)\n\t\t\t\tres = json_object_get(val, \"reject-reason\");\n\t\t\tif (res) {\n\t\t\t\tconst char *reasontmp = json_string_value(res);\n\n\t\t\t\tsize_t reasonLen = strlen(reasontmp);\n\t\t\t\tif (reasonLen > 28)\n\t\t\t\t\treasonLen = 28;\n\t\t\t\treason[0] = ' '; reason[1] = '(';\n\t\t\t\tmemcpy(2 + reason, reasontmp, reasonLen);\n\t\t\t\treason[reasonLen + 2] = ')'; reason[reasonLen + 3] = '\\0';\n\t\t\t\tmemcpy(disposition + 7, reasontmp, reasonLen);\n\t\t\t\tdisposition[6] = ':'; disposition[reasonLen + 7] = '\\0';\n\t\t\t} else if (work->stratum && err && json_is_array(err)) {\n\t\t\t\tjson_t *reason_val = json_array_get(err, 1);\n\t\t\t\tchar *reason_str;\n\n\t\t\t\tif (reason_val && json_is_string(reason_val)) {\n\t\t\t\t\treason_str = (char *)json_string_value(reason_val);\n\t\t\t\t\tsnprintf(reason, 31, \" (%s)\", reason_str);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tapplog(LOG_NOTICE, \"Rejected %s %s %d %s%s %s%s\",\n\t\t\t       hashshow, cgpu->drv->name, cgpu->device_id, where, reason, resubmit ? \"(resubmit)\" : \"\", worktime);\n\t\t\tsharelog(disposition, work);\n\t\t}\n\n\t\t/* Once we have more than a nominal amount of sequential rejects,\n\t\t * at least 10 and more than 3 mins at the current utility,\n\t\t * disable the pool because some pool error is likely to have\n\t\t * ensued. Do not do this if we know the share just happened to\n\t\t * be stale due to networking delays.\n\t\t */\n\t\tif (pool->seq_rejects > 10 && !work->stale && opt_disable_pool && enabled_pools > 1) {\n\t\t\tdouble utility = total_accepted / total_secs * 60;\n\n\t\t\tif (pool->seq_rejects > utility * 3) {\n\t\t\t\tapplog(LOG_WARNING, \"Pool %d rejected %d sequential shares, disabling!\",\n\t\t\t\t       pool->pool_no, pool->seq_rejects);\n\t\t\t\treject_pool(pool);\n\t\t\t\tif (pool == current_pool())\n\t\t\t\t\tswitch_pools(NULL);\n\t\t\t\tpool->seq_rejects = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic bool submit_upstream_work(struct work *work, CURL *curl, bool resubmit)\n{\n\tchar *hexstr = NULL;\n\tjson_t *val, *res, *err;\n\tchar *s;\n\tbool rc = false;\n\tint thr_id = work->thr_id;\n\tstruct cgpu_info *cgpu;\n\tstruct pool *pool = work->pool;\n\tint rolltime;\n\tstruct timeval tv_submit, tv_submit_reply;\n\tchar hashshow[64 + 4] = \"\";\n\tchar worktime[200] = \"\";\n\n\tcgpu = get_thr_cgpu(thr_id);\n\n\tendian_flip128(work->data, work->data);\n\n\t/* build hex string */\n\thexstr = bin2hex(work->data, sizeof(work->data));\n\n\t/* build JSON-RPC request */\n\tif (work->gbt) {\n\t\tchar *gbt_block, *varint;\n\t\tunsigned char data[80];\n\n\t\tflip80(data, work->data);\n\t\tgbt_block = bin2hex(data, 80);\n\n\t\tif (work->gbt_txns < 0xfd) {\n\t\t\tuint8_t val = work->gbt_txns;\n\n\t\t\tvarint = bin2hex((const unsigned char *)&val, 1);\n\t\t} else if (work->gbt_txns <= 0xffff) {\n\t\t\tuint16_t val = htole16(work->gbt_txns);\n\n\t\t\tgbt_block = realloc_strcat(gbt_block, \"fd\");\n\t\t\tvarint = bin2hex((const unsigned char *)&val, 2);\n\t\t} else {\n\t\t\tuint32_t val = htole32(work->gbt_txns);\n\n\t\t\tgbt_block = realloc_strcat(gbt_block, \"fe\");\n\t\t\tvarint = bin2hex((const unsigned char *)&val, 4);\n\t\t}\n\t\tgbt_block = realloc_strcat(gbt_block, varint);\n\t\tfree(varint);\n\t\tgbt_block = realloc_strcat(gbt_block, work->gbt_coinbase);\n\n\t\ts = strdup(\"{\\\"id\\\": 0, \\\"method\\\": \\\"submitblock\\\", \\\"params\\\": [\\\"\");\n\t\ts = realloc_strcat(s, gbt_block);\n\t\tif (work->job_id) {\n\t\t\ts = realloc_strcat(s, \"\\\", {\\\"workid\\\": \\\"\");\n\t\t\ts = realloc_strcat(s, work->job_id);\n\t\t\ts = realloc_strcat(s, \"\\\"}]}\");\n\t\t} else\n\t\t\ts = realloc_strcat(s, \"\\\", {}]}\");\n\t\tfree(gbt_block);\n\t} else {\n\t\ts = strdup(\"{\\\"method\\\": \\\"getwork\\\", \\\"params\\\": [ \\\"\");\n\t\ts = realloc_strcat(s, hexstr);\n\t\ts = realloc_strcat(s, \"\\\" ], \\\"id\\\":1}\");\n\t}\n\tapplog(LOG_DEBUG, \"DBG: sending %s submit RPC call: %s\", pool->rpc_url, s);\n\ts = realloc_strcat(s, \"\\n\");\n\n\tcgtime(&tv_submit);\n\t/* issue JSON-RPC request */\n\tval = json_rpc_call(curl, pool->rpc_url, pool->rpc_userpass, s, false, false, &rolltime, pool, true);\n\tcgtime(&tv_submit_reply);\n\tfree(s);\n\n\tif (unlikely(!val)) {\n\t\tapplog(LOG_INFO, \"submit_upstream_work json_rpc_call failed\");\n\t\tif (!pool_tset(pool, &pool->submit_fail)) {\n\t\t\ttotal_ro++;\n\t\t\tpool->remotefail_occasions++;\n\t\t\tapplog(LOG_WARNING, \"Pool %d communication failure, caching submissions\", pool->pool_no);\n\t\t}\n\t\tnmsleep(5000);\n\t\tgoto out;\n\t} else if (pool_tclear(pool, &pool->submit_fail))\n\t\tapplog(LOG_WARNING, \"Pool %d communication resumed, submitting work\", pool->pool_no);\n\n\tres = json_object_get(val, \"result\");\n\terr = json_object_get(val, \"error\");\n\n\tif (!QUIET) {\n\t\tint intdiff = floor(work->work_difficulty);\n\t\tchar diffdisp[16], *outhash;\n\t\tunsigned char rhash[32];\n\n\t\tswab256(rhash, work->hash);\n\t\tif (opt_scrypt)\n\t\t\touthash = bin2hex(rhash + 2, 4);\n\t\telse\n\t\t\touthash = bin2hex(rhash + 4, 4);\n\t\tsuffix_string(work->share_diff, diffdisp, 0);\n\t\tsprintf(hashshow, \"%s Diff %s/%d%s\", outhash, diffdisp, intdiff,\n\t\t\twork->block? \" BLOCK!\" : \"\");\n\t\tfree(outhash);\n\n\t\tif (opt_worktime) {\n\t\t\tchar workclone[20];\n\t\t\tstruct tm *tm, tm_getwork, tm_submit_reply;\n\t\t\tdouble getwork_time = tdiff((struct timeval *)&(work->tv_getwork_reply),\n\t\t\t\t\t\t\t(struct timeval *)&(work->tv_getwork));\n\t\t\tdouble getwork_to_work = tdiff((struct timeval *)&(work->tv_work_start),\n\t\t\t\t\t\t\t(struct timeval *)&(work->tv_getwork_reply));\n\t\t\tdouble work_time = tdiff((struct timeval *)&(work->tv_work_found),\n\t\t\t\t\t\t\t(struct timeval *)&(work->tv_work_start));\n\t\t\tdouble work_to_submit = tdiff(&tv_submit,\n\t\t\t\t\t\t\t(struct timeval *)&(work->tv_work_found));\n\t\t\tdouble submit_time = tdiff(&tv_submit_reply, &tv_submit);\n\t\t\tint diffplaces = 3;\n\n\t\t\ttime_t tmp_time = work->tv_getwork.tv_sec;\n\t\t\ttm = localtime(&tmp_time);\n\t\t\tmemcpy(&tm_getwork, tm, sizeof(struct tm));\n\t\t\ttmp_time = tv_submit_reply.tv_sec;\n\t\t\ttm = localtime(&tmp_time);\n\t\t\tmemcpy(&tm_submit_reply, tm, sizeof(struct tm));\n\n\t\t\tif (work->clone) {\n\t\t\t\tsprintf(workclone, \"C:%1.3f\",\n\t\t\t\t\ttdiff((struct timeval *)&(work->tv_cloned),\n\t\t\t\t\t\t(struct timeval *)&(work->tv_getwork_reply)));\n\t\t\t}\n\t\t\telse\n\t\t\t\tstrcpy(workclone, \"O\");\n\n\t\t\tif (work->work_difficulty < 1)\n\t\t\t\tdiffplaces = 6;\n\n\t\t\tsprintf(worktime, \" <-%08lx.%08lx M:%c D:%1.*f G:%02d:%02d:%02d:%1.3f %s (%1.3f) W:%1.3f (%1.3f) S:%1.3f R:%02d:%02d:%02d\",\n\t\t\t\t(unsigned long)swab32(*(uint32_t *)&(work->data[opt_scrypt ? 32 : 28])),\n\t\t\t\t(unsigned long)swab32(*(uint32_t *)&(work->data[opt_scrypt ? 28 : 24])),\n\t\t\t\twork->getwork_mode, diffplaces, work->work_difficulty,\n\t\t\t\ttm_getwork.tm_hour, tm_getwork.tm_min,\n\t\t\t\ttm_getwork.tm_sec, getwork_time, workclone,\n\t\t\t\tgetwork_to_work, work_time, work_to_submit, submit_time,\n\t\t\t\ttm_submit_reply.tm_hour, tm_submit_reply.tm_min,\n\t\t\t\ttm_submit_reply.tm_sec);\n\t\t}\n\t}\n\n\tshare_result(val, res, err, work, hashshow, resubmit, worktime);\n\n\tcgpu->utility = cgpu->accepted / total_secs * 60;\n\n\tif (!opt_realquiet)\n\t\tprint_status(thr_id);\n\tif (!want_per_device_stats) {\n\t\tchar logline[256];\n\n\t\tget_statline(logline, cgpu);\n\t\tapplog(LOG_INFO, \"%s\", logline);\n\t}\n\n\tjson_decref(val);\n\n\trc = true;\nout:\n\tfree(hexstr);\n\treturn rc;\n}\n\n/* Specifies whether we can use this pool for work or not. */\nstatic bool pool_unworkable(struct pool *pool)\n{\n\tif (pool->idle)\n\t\treturn true;\n\tif (pool->enabled != POOL_ENABLED)\n\t\treturn true;\n\tif (pool->has_stratum && !pool->stratum_active)\n\t\treturn true;\n\treturn false;\n}\n\n/* In balanced mode, the amount of diff1 solutions per pool is monitored as a\n * rolling average per 10 minutes and if pools start getting more, it biases\n * away from them to distribute work evenly. The share count is reset to the\n * rolling average every 10 minutes to not send all work to one pool after it\n * has been disabled/out for an extended period. */\nstatic struct pool *select_balanced(struct pool *cp)\n{\n\tint i, lowest = cp->shares;\n\tstruct pool *ret = cp;\n\n\tfor (i = 0; i < total_pools; i++) {\n\t\tstruct pool *pool = pools[i];\n\n\t\tif (pool_unworkable(pool))\n\t\t\tcontinue;\n\t\tif (pool->shares < lowest) {\n\t\t\tlowest = pool->shares;\n\t\t\tret = pool;\n\t\t}\n\t}\n\n\tret->shares++;\n\treturn ret;\n}\n\n/* Select any active pool in a rotating fashion when loadbalance is chosen */\nstatic inline struct pool *select_pool(bool lagging)\n{\n\tstatic int rotating_pool = 0;\n\tstruct pool *pool, *cp;\n\tint tested;\n\n\tcp = current_pool();\n\n\tif (pool_strategy == POOL_BALANCE)\n\t\treturn select_balanced(cp);\n\n\tif (pool_strategy != POOL_LOADBALANCE && (!lagging || opt_fail_only))\n\t\tpool = cp;\n\telse\n\t\tpool = NULL;\n\n\t/* Try to find the first pool in the rotation that is usable */\n\ttested = 0;\n\twhile (!pool && tested++ < total_pools) {\n\t\tif (++rotating_pool >= total_pools)\n\t\t\trotating_pool = 0;\n\t\tpool = pools[rotating_pool];\n\t\tif (!pool_unworkable(pool))\n\t\t\tbreak;\n\t\tpool = NULL;\n\t}\n\t/* If still nothing is usable, use the current pool */\n\tif (!pool)\n\t\tpool = cp;\n\n\treturn pool;\n}\n\nstatic double DIFFEXACTONE = 26959946667150639794667015087019630673637144422540572481103610249215.0;\nstatic const uint64_t diffone = 0xFFFF000000000000ull;\n\n/*\n * Calculate the work share difficulty\n */\nstatic void calc_diff(struct work *work, int known)\n{\n\tstruct cgminer_pool_stats *pool_stats = &(work->pool->cgminer_pool_stats);\n\tdouble difficulty;\n\n\tif (opt_scrypt) {\n\t\tuint64_t *data64, d64;\n\t\tchar rtarget[32];\n\n\t\tswab256(rtarget, work->target);\n\t\tdata64 = (uint64_t *)(rtarget + 2);\n\t\td64 = be64toh(*data64);\n\t\tif (unlikely(!d64))\n\t\t\td64 = 1;\n\t\twork->work_difficulty = diffone / d64;\n\t} else if (!known) {\n\t\tdouble targ = 0;\n\t\tint i;\n\n\t\tfor (i = 31; i >= 0; i--) {\n\t\t\ttarg *= 256;\n\t\t\ttarg += work->target[i];\n\t\t}\n\n\t\twork->work_difficulty = DIFFEXACTONE / (targ ? : DIFFEXACTONE);\n\t} else\n\t\twork->work_difficulty = known;\n\tdifficulty = work->work_difficulty;\n\n\tpool_stats->last_diff = difficulty;\n\tsuffix_string((uint64_t)difficulty, work->pool->diff, 0);\n\n\tif (difficulty == pool_stats->min_diff)\n\t\tpool_stats->min_diff_count++;\n\telse if (difficulty < pool_stats->min_diff || pool_stats->min_diff == 0) {\n\t\tpool_stats->min_diff = difficulty;\n\t\tpool_stats->min_diff_count = 1;\n\t}\n\n\tif (difficulty == pool_stats->max_diff)\n\t\tpool_stats->max_diff_count++;\n\telse if (difficulty > pool_stats->max_diff) {\n\t\tpool_stats->max_diff = difficulty;\n\t\tpool_stats->max_diff_count = 1;\n\t}\n}\n\nstatic void get_benchmark_work(struct work *work)\n{\n\t// Use a random work block pulled from a pool\n\tstatic uint8_t bench_block[] = { CGMINER_BENCHMARK_BLOCK };\n\n\tsize_t bench_size = sizeof(*work);\n\tsize_t work_size = sizeof(bench_block);\n\tsize_t min_size = (work_size < bench_size ? work_size : bench_size);\n\tmemset(work, 0, sizeof(*work));\n\tmemcpy(work, &bench_block, min_size);\n\twork->mandatory = true;\n\twork->pool = pools[0];\n\tcgtime(&work->tv_getwork);\n\tcopy_time(&work->tv_getwork_reply, &work->tv_getwork);\n\twork->getwork_mode = GETWORK_MODE_BENCHMARK;\n\tcalc_diff(work, 0);\n}\n\nstatic bool get_upstream_work(struct work *work, CURL *curl)\n{\n\tstruct pool *pool = work->pool;\n\tstruct cgminer_pool_stats *pool_stats = &(pool->cgminer_pool_stats);\n\tstruct timeval tv_elapsed;\n\tjson_t *val = NULL;\n\tbool rc = false;\n\tchar *url;\n\n\tapplog(LOG_DEBUG, \"DBG: sending %s get RPC call: %s\", pool->rpc_url, pool->rpc_req);\n\n\turl = pool->rpc_url;\n\n\tcgtime(&work->tv_getwork);\n\n\tval = json_rpc_call(curl, url, pool->rpc_userpass, pool->rpc_req, false,\n\t\t\t    false, &work->rolltime, pool, false);\n\tpool_stats->getwork_attempts++;\n\n\tif (likely(val)) {\n\t\trc = work_decode(pool, work, val);\n\t\tif (unlikely(!rc))\n\t\t\tapplog(LOG_DEBUG, \"Failed to decode work in get_upstream_work\");\n\t} else\n\t\tapplog(LOG_DEBUG, \"Failed json_rpc_call in get_upstream_work\");\n\n\tcgtime(&work->tv_getwork_reply);\n\ttimersub(&(work->tv_getwork_reply), &(work->tv_getwork), &tv_elapsed);\n\tpool_stats->getwork_wait_rolling += ((double)tv_elapsed.tv_sec + ((double)tv_elapsed.tv_usec / 1000000)) * 0.63;\n\tpool_stats->getwork_wait_rolling /= 1.63;\n\n\ttimeradd(&tv_elapsed, &(pool_stats->getwork_wait), &(pool_stats->getwork_wait));\n\tif (timercmp(&tv_elapsed, &(pool_stats->getwork_wait_max), >)) {\n\t\tpool_stats->getwork_wait_max.tv_sec = tv_elapsed.tv_sec;\n\t\tpool_stats->getwork_wait_max.tv_usec = tv_elapsed.tv_usec;\n\t}\n\tif (timercmp(&tv_elapsed, &(pool_stats->getwork_wait_min), <)) {\n\t\tpool_stats->getwork_wait_min.tv_sec = tv_elapsed.tv_sec;\n\t\tpool_stats->getwork_wait_min.tv_usec = tv_elapsed.tv_usec;\n\t}\n\tpool_stats->getwork_calls++;\n\n\twork->pool = pool;\n\twork->longpoll = false;\n\twork->getwork_mode = GETWORK_MODE_POOL;\n\tcalc_diff(work, 0);\n\ttotal_getworks++;\n\tpool->getwork_requested++;\n\n\tif (likely(val))\n\t\tjson_decref(val);\n\n\treturn rc;\n}\n\n#ifdef HAVE_CURSES\nstatic void disable_curses(void)\n{\n\tif (curses_active_locked()) {\n\t\tuse_curses = false;\n\t\tcurses_active = false;\n\t\tleaveok(logwin, false);\n\t\tleaveok(statuswin, false);\n\t\tleaveok(mainwin, false);\n\t\tnocbreak();\n\t\techo();\n\t\tdelwin(logwin);\n\t\tdelwin(statuswin);\n\t\tdelwin(mainwin);\n\t\tendwin();\n#ifdef WIN32\n\t\t// Move the cursor to after curses output.\n\t\tHANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);\n\t\tCONSOLE_SCREEN_BUFFER_INFO csbi;\n\t\tCOORD coord;\n\n\t\tif (GetConsoleScreenBufferInfo(hout, &csbi)) {\n\t\t\tcoord.X = 0;\n\t\t\tcoord.Y = csbi.dwSize.Y - 1;\n\t\t\tSetConsoleCursorPosition(hout, coord);\n\t\t}\n#endif\n\t\tunlock_curses();\n\t}\n}\n#endif\n\nstatic void __kill_work(void)\n{\n\tstruct thr_info *thr;\n\tint i;\n\n\tif (!successful_connect)\n\t\treturn;\n\n\tapplog(LOG_INFO, \"Received kill message\");\n\n#ifdef USE_USBUTILS\n\t/* Best to get rid of it first so it doesn't\n\t * try to create any new devices */\n\tif (!opt_scrypt) {\n\t\tapplog(LOG_DEBUG, \"Killing off HotPlug thread\");\n\t\tthr = &control_thr[hotplug_thr_id];\n\t\tthr_info_cancel(thr);\n\t}\n#endif\n\n\tapplog(LOG_DEBUG, \"Killing off watchpool thread\");\n\t/* Kill the watchpool thread */\n\tthr = &control_thr[watchpool_thr_id];\n\tthr_info_cancel(thr);\n\n\tapplog(LOG_DEBUG, \"Killing off watchdog thread\");\n\t/* Kill the watchdog thread */\n\tthr = &control_thr[watchdog_thr_id];\n\tthr_info_cancel(thr);\n\n\tapplog(LOG_DEBUG, \"Stopping mining threads\");\n\t/* Stop the mining threads*/\n\tfor (i = 0; i < mining_threads; i++) {\n\t\tthr = get_thread(i);\n\t\tthr_info_freeze(thr);\n\t\tthr->pause = true;\n\t}\n\n\tnmsleep(1000);\n\n\tapplog(LOG_DEBUG, \"Killing off mining threads\");\n\t/* Kill the mining threads*/\n\tfor (i = 0; i < mining_threads; i++) {\n\t\tthr = get_thread(i);\n\t\tthr_info_cancel(thr);\n\t}\n\n\tapplog(LOG_DEBUG, \"Killing off stage thread\");\n\t/* Stop the others */\n\tthr = &control_thr[stage_thr_id];\n\tthr_info_cancel(thr);\n\n\tapplog(LOG_DEBUG, \"Killing off API thread\");\n\tthr = &control_thr[api_thr_id];\n\tthr_info_cancel(thr);\n\n#ifdef USE_USBUTILS\n\t/* Release USB resources in case it's a restart\n\t * and not a QUIT */\n\tif (!opt_scrypt) {\n\t\tapplog(LOG_DEBUG, \"Releasing all USB devices\");\n\t\tusb_cleanup();\n\t}\n#endif\n\n}\n\n/* This should be the common exit path */\nvoid kill_work(void)\n{\n\t__kill_work();\n\n\tquit(0, \"Shutdown signal received.\");\n}\n\nstatic\n#ifdef WIN32\nconst\n#endif\nchar **initial_args;\n\nstatic void clean_up(void);\n\nvoid app_restart(void)\n{\n\tapplog(LOG_WARNING, \"Attempting to restart %s\", packagename);\n\n\t__kill_work();\n\tclean_up();\n\n#if defined(unix)\n\tif (forkpid > 0) {\n\t\tkill(forkpid, SIGTERM);\n\t\tforkpid = 0;\n\t}\n#endif\n\n\texecv(initial_args[0], (EXECV_2ND_ARG_TYPE)initial_args);\n\tapplog(LOG_WARNING, \"Failed to restart application\");\n}\n\nstatic void sighandler(int __maybe_unused sig)\n{\n\t/* Restore signal handlers so we can still quit if kill_work fails */\n\tsigaction(SIGTERM, &termhandler, NULL);\n\tsigaction(SIGINT, &inthandler, NULL);\n\tkill_work();\n}\n\n/* Called with pool_lock held. Recruit an extra curl if none are available for\n * this pool. */\nstatic void recruit_curl(struct pool *pool)\n{\n\tstruct curl_ent *ce = calloc(sizeof(struct curl_ent), 1);\n\n\tif (unlikely(!ce))\n\t\tquit(1, \"Failed to calloc in recruit_curl\");\n\n\tce->curl = curl_easy_init();\n\tif (unlikely(!ce->curl))\n\t\tquit(1, \"Failed to init in recruit_curl\");\n\n\tlist_add(&ce->node, &pool->curlring);\n\tpool->curls++;\n}\n\n/* Grab an available curl if there is one. If not, then recruit extra curls\n * unless we are in a submit_fail situation, or we have opt_delaynet enabled\n * and there are already 5 curls in circulation. Limit total number to the\n * number of mining threads per pool as well to prevent blasting a pool during\n * network delays/outages. */\nstatic struct curl_ent *pop_curl_entry(struct pool *pool)\n{\n\tint curl_limit = opt_delaynet ? 5 : (mining_threads + opt_queue) * 2;\n\tbool recruited = false;\n\tstruct curl_ent *ce;\n\n\tmutex_lock(&pool->pool_lock);\nretry:\n\tif (!pool->curls) {\n\t\trecruit_curl(pool);\n\t\trecruited = true;\n\t} else if (list_empty(&pool->curlring)) {\n\t\tif (pool->curls >= curl_limit) {\n\t\t\tpthread_cond_wait(&pool->cr_cond, &pool->pool_lock);\n\t\t\tgoto retry;\n\t\t} else {\n\t\t\trecruit_curl(pool);\n\t\t\trecruited = true;\n\t\t}\n\t}\n\tce = list_entry(pool->curlring.next, struct curl_ent, node);\n\tlist_del(&ce->node);\n\tmutex_unlock(&pool->pool_lock);\n\n\tif (recruited)\n\t\tapplog(LOG_DEBUG, \"Recruited curl for pool %d\", pool->pool_no);\n\treturn ce;\n}\n\nstatic void push_curl_entry(struct curl_ent *ce, struct pool *pool)\n{\n\tmutex_lock(&pool->pool_lock);\n\tlist_add_tail(&ce->node, &pool->curlring);\n\tcgtime(&ce->tv);\n\tpthread_cond_broadcast(&pool->cr_cond);\n\tmutex_unlock(&pool->pool_lock);\n}\n\nstatic bool stale_work(struct work *work, bool share);\n\nstatic inline bool should_roll(struct work *work)\n{\n\tstruct timeval now;\n\ttime_t expiry;\n\n\tif (work->pool != current_pool() && pool_strategy != POOL_LOADBALANCE && pool_strategy != POOL_BALANCE)\n\t\treturn false;\n\n\tif (work->rolltime > opt_scantime)\n\t\texpiry = work->rolltime;\n\telse\n\t\texpiry = opt_scantime;\n\texpiry = expiry * 2 / 3;\n\n\t/* We shouldn't roll if we're unlikely to get one shares' duration\n\t * work out of doing so */\n\tcgtime(&now);\n\tif (now.tv_sec - work->tv_staged.tv_sec > expiry)\n\t\treturn false;\n\t\n\treturn true;\n}\n\n/* Limit rolls to 7000 to not beyond 2 hours in the future where bitcoind will\n * reject blocks as invalid. */\nstatic inline bool can_roll(struct work *work)\n{\n\treturn (!work->stratum && work->pool && work->rolltime && !work->clone &&\n\t\twork->rolls < 7000 && !stale_work(work, false));\n}\n\nstatic void roll_work(struct work *work)\n{\n\tuint32_t *work_ntime;\n\tuint32_t ntime;\n\n\twork_ntime = (uint32_t *)(work->data + 68);\n\tntime = be32toh(*work_ntime);\n\tntime++;\n\t*work_ntime = htobe32(ntime);\n\tlocal_work++;\n\twork->rolls++;\n\twork->blk.nonce = 0;\n\tapplog(LOG_DEBUG, \"Successfully rolled work\");\n\n\t/* This is now a different work item so it needs a different ID for the\n\t * hashtable */\n\twork->id = total_work++;\n}\n\n/* Duplicates any dynamically allocated arrays within the work struct to\n * prevent a copied work struct from freeing ram belonging to another struct */\nvoid __copy_work(struct work *work, struct work *base_work)\n{\n\tint id = work->id;\n\n\tclean_work(work);\n\tmemcpy(work, base_work, sizeof(struct work));\n\t/* Keep the unique new id assigned during make_work to prevent copied\n\t * work from having the same id. */\n\twork->id = id;\n\tif (base_work->job_id)\n\t\twork->job_id = strdup(base_work->job_id);\n\tif (base_work->nonce1)\n\t\twork->nonce1 = strdup(base_work->nonce1);\n\tif (base_work->nonce2)\n\t\twork->nonce2 = strdup(base_work->nonce2);\n\tif (base_work->ntime)\n\t\twork->ntime = strdup(base_work->ntime);\n\tif (base_work->gbt_coinbase)\n\t\twork->gbt_coinbase = strdup(base_work->gbt_coinbase);\n}\n\n/* Generates a copy of an existing work struct, creating fresh heap allocations\n * for all dynamically allocated arrays within the struct */\nstruct work *copy_work(struct work *base_work)\n{\n\tstruct work *work = make_work();\n\n\t__copy_work(work, base_work);\n\n\treturn work;\n}\n\nstatic struct work *make_clone(struct work *work)\n{\n\tstruct work *work_clone = copy_work(work);\n\n\twork_clone->clone = true;\n\tcgtime((struct timeval *)&(work_clone->tv_cloned));\n\twork_clone->longpoll = false;\n\twork_clone->mandatory = false;\n\t/* Make cloned work appear slightly older to bias towards keeping the\n\t * master work item which can be further rolled */\n\twork_clone->tv_staged.tv_sec -= 1;\n\n\treturn work_clone;\n}\n\nstatic void stage_work(struct work *work);\n\nstatic bool clone_available(void)\n{\n\tstruct work *work_clone = NULL, *work, *tmp;\n\tbool cloned = false;\n\n\tmutex_lock(stgd_lock);\n\tif (!staged_rollable)\n\t\tgoto out_unlock;\n\n\tHASH_ITER(hh, staged_work, work, tmp) {\n\t\tif (can_roll(work) && should_roll(work)) {\n\t\t\troll_work(work);\n\t\t\twork_clone = make_clone(work);\n\t\t\troll_work(work);\n\t\t\tcloned = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\nout_unlock:\n\tmutex_unlock(stgd_lock);\n\n\tif (cloned) {\n\t\tapplog(LOG_DEBUG, \"Pushing cloned available work to stage thread\");\n\t\tstage_work(work_clone);\n\t}\n\treturn cloned;\n}\n\nstatic void pool_died(struct pool *pool)\n{\n\tif (!pool_tset(pool, &pool->idle)) {\n\t\tcgtime(&pool->tv_idle);\n\t\tif (pool == current_pool()) {\n\t\t\tapplog(LOG_WARNING, \"Pool %d %s not responding!\", pool->pool_no, pool->rpc_url);\n\t\t\tswitch_pools(NULL);\n\t\t} else\n\t\t\tapplog(LOG_INFO, \"Pool %d %s failed to return work\", pool->pool_no, pool->rpc_url);\n\t}\n}\n\nstatic bool stale_work(struct work *work, bool share)\n{\n\tstruct timeval now;\n\ttime_t work_expiry;\n\tstruct pool *pool;\n\tint getwork_delay;\n\n\tif (opt_benchmark)\n\t\treturn false;\n\n\tif (work->work_block != work_block) {\n\t\tapplog(LOG_DEBUG, \"Work stale due to block mismatch\");\n\t\treturn true;\n\t}\n\n\t/* Technically the rolltime should be correct but some pools\n\t * advertise a broken expire= that is lower than a meaningful\n\t * scantime */\n\tif (work->rolltime > opt_scantime)\n\t\twork_expiry = work->rolltime;\n\telse\n\t\twork_expiry = opt_expiry;\n\n\tpool = work->pool;\n\n\tif (!share && pool->has_stratum) {\n\t\tbool same_job;\n\n\t\tif (!pool->stratum_active || !pool->stratum_notify) {\n\t\t\tapplog(LOG_DEBUG, \"Work stale due to stratum inactive\");\n\t\t\treturn true;\n\t\t}\n\n\t\tsame_job = true;\n\n\t\tcg_rlock(&pool->data_lock);\n\t\tif (strcmp(work->job_id, pool->swork.job_id))\n\t\t\tsame_job = false;\n\t\tcg_runlock(&pool->data_lock);\n\n\t\tif (!same_job) {\n\t\t\tapplog(LOG_DEBUG, \"Work stale due to stratum job_id mismatch\");\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t/* Factor in the average getwork delay of this pool, rounding it up to\n\t * the nearest second */\n\tgetwork_delay = pool->cgminer_pool_stats.getwork_wait_rolling * 5 + 1;\n\twork_expiry -= getwork_delay;\n\tif (unlikely(work_expiry < 5))\n\t\twork_expiry = 5;\n\n\tcgtime(&now);\n\tif ((now.tv_sec - work->tv_staged.tv_sec) >= work_expiry) {\n\t\tapplog(LOG_DEBUG, \"Work stale due to expiry\");\n\t\treturn true;\n\t}\n\n\tif (opt_fail_only && !share && pool != current_pool() && !work->mandatory &&\n\t    pool_strategy != POOL_LOADBALANCE && pool_strategy != POOL_BALANCE) {\n\t\tapplog(LOG_DEBUG, \"Work stale due to fail only pool mismatch\");\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nstatic uint64_t share_diff(const struct work *work)\n{\n\tuint64_t *data64, d64, ret;\n\tbool new_best = false;\n\tchar rhash[32];\n\n\tswab256(rhash, work->hash);\n\tif (opt_scrypt)\n\t\tdata64 = (uint64_t *)(rhash + 2);\n\telse\n\t\tdata64 = (uint64_t *)(rhash + 4);\n\td64 = be64toh(*data64);\n\tif (unlikely(!d64))\n\t\td64 = 1;\n\tret = diffone / d64;\n\n\tcg_wlock(&control_lock);\n\tif (unlikely(ret > best_diff)) {\n\t\tnew_best = true;\n\t\tbest_diff = ret;\n\t\tsuffix_string(best_diff, best_share, 0);\n\t}\n\tif (unlikely(ret > work->pool->best_diff))\n\t\twork->pool->best_diff = ret;\n\tcg_wunlock(&control_lock);\n\n\tif (unlikely(new_best))\n\t\tapplog(LOG_INFO, \"New best share: %s\", best_share);\n\n\treturn ret;\n}\n\nstatic void regen_hash(struct work *work)\n{\n\tuint32_t *data32 = (uint32_t *)(work->data);\n\tunsigned char swap[80];\n\tuint32_t *swap32 = (uint32_t *)swap;\n\tunsigned char hash1[32];\n\n\tflip80(swap32, data32);\n\tsha2(swap, 80, hash1);\n\tsha2(hash1, 32, (unsigned char *)(work->hash));\n}\n\nstatic void rebuild_hash(struct work *work)\n{\n\tif (opt_scrypt)\n\t\tscrypt_regenhash(work);\n\telse\n\t\tregen_hash(work);\n\n#if 0\t// KRAMBLE\n\tchar *datastr = bin2hex(work->data, 80);\n\tchar *hashstr = bin2hex(work->hash, 32);\n\n\tapplog(LOG_WARNING, \"data %s hash %s\", datastr, hashstr);\n\t// applog(LOG_WARNING, \"hash %s\", hashstr);\n#endif\n\n\twork->share_diff = share_diff(work);\n\tif (unlikely(work->share_diff >= current_diff)) {\n\t\twork->block = true;\n\t\twork->pool->solved++;\n\t\tfound_blocks++;\n\t\twork->mandatory = true;\n\t\tapplog(LOG_NOTICE, \"Found block for pool %d!\", work->pool->pool_no);\n\t}\n}\n\nstatic bool cnx_needed(struct pool *pool);\n\nstatic void *submit_work_thread(void *userdata)\n{\n\tstruct work *work = (struct work *)userdata;\n\tstruct pool *pool = work->pool;\n\tbool resubmit = false;\n\tstruct curl_ent *ce;\n\n\tpthread_detach(pthread_self());\n\n\tRenameThread(\"submit_work\");\n\n\tapplog(LOG_DEBUG, \"Creating extra submit work thread\");\n\n\tif (stale_work(work, true)) {\n\t\tif (opt_submit_stale)\n\t\t\tapplog(LOG_NOTICE, \"Pool %d stale share detected, submitting as user requested\", pool->pool_no);\n\t\telse if (pool->submit_old)\n\t\t\tapplog(LOG_NOTICE, \"Pool %d stale share detected, submitting as pool requested\", pool->pool_no);\n\t\telse {\n\t\t\tapplog(LOG_NOTICE, \"Pool %d stale share detected, discarding\", pool->pool_no);\n\t\t\tsharelog(\"discard\", work);\n\n\t\t\tmutex_lock(&stats_lock);\n\t\t\ttotal_stale++;\n\t\t\tpool->stale_shares++;\n\t\t\ttotal_diff_stale += work->work_difficulty;\n\t\t\tpool->diff_stale += work->work_difficulty;\n\t\t\tmutex_unlock(&stats_lock);\n\n\t\t\tgoto out;\n\t\t}\n\t\twork->stale = true;\n\t}\n\n\tif (work->stratum) {\n\t\tstruct stratum_share *sshare = calloc(sizeof(struct stratum_share), 1);\n\t\tuint32_t *hash32 = (uint32_t *)work->hash, nonce;\n\t\tbool submitted = false;\n\t\tchar *noncehex;\n\t\tchar s[1024];\n\n\t\tsshare->sshare_time = time(NULL);\n\t\t/* This work item is freed in parse_stratum_response */\n\t\tsshare->work = work;\n\t\tnonce = *((uint32_t *)(work->data + 76));\n\t\tnoncehex = bin2hex((const unsigned char *)&nonce, 4);\n\t\tmemset(s, 0, 1024);\n\n\t\tmutex_lock(&sshare_lock);\n\t\t/* Give the stratum share a unique id */\n\t\tsshare->id = swork_id++;\n\t\tmutex_unlock(&sshare_lock);\n\n\t\tsprintf(s, \"{\\\"params\\\": [\\\"%s\\\", \\\"%s\\\", \\\"%s\\\", \\\"%s\\\", \\\"%s\\\"], \\\"id\\\": %d, \\\"method\\\": \\\"mining.submit\\\"}\",\n\t\t\tpool->rpc_user, work->job_id, work->nonce2, work->ntime, noncehex, sshare->id);\n\t\tfree(noncehex);\n\n\t\tapplog(LOG_INFO, \"Submitting share %08lx to pool %d\",\n\t\t\t\t\t(long unsigned int)htole32(hash32[6]), pool->pool_no);\n\n\t\t/* Try resubmitting for up to 2 minutes if we fail to submit\n\t\t * once and the stratum pool nonce1 still matches suggesting\n\t\t * we may be able to resume. */\n\t\twhile (time(NULL) < sshare->sshare_time + 120) {\n\t\t\tbool sessionid_match;\n\n\t\t\tif (likely(stratum_send(pool, s, strlen(s)))) {\n\t\t\t\tif (pool_tclear(pool, &pool->submit_fail))\n\t\t\t\t\t\tapplog(LOG_WARNING, \"Pool %d communication resumed, submitting work\", pool->pool_no);\n\n\t\t\t\tmutex_lock(&sshare_lock);\n\t\t\t\tHASH_ADD_INT(stratum_shares, id, sshare);\n\t\t\t\tpool->sshares++;\n\t\t\t\tmutex_unlock(&sshare_lock);\n\n\t\t\t\tapplog(LOG_DEBUG, \"Successfully submitted, adding to stratum_shares db\");\n\t\t\t\tsubmitted = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!pool_tset(pool, &pool->submit_fail) && cnx_needed(pool)) {\n\t\t\t\tapplog(LOG_WARNING, \"Pool %d stratum share submission failure\", pool->pool_no);\n\t\t\t\ttotal_ro++;\n\t\t\t\tpool->remotefail_occasions++;\n\t\t\t}\n\n\t\t\tcg_rlock(&pool->data_lock);\n\t\t\tsessionid_match = (pool->nonce1 && !strcmp(work->nonce1, pool->nonce1));\n\t\t\tcg_runlock(&pool->data_lock);\n\n\t\t\tif (!sessionid_match) {\n\t\t\t\tapplog(LOG_DEBUG, \"No matching session id for resubmitting stratum share\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* Retry every 5 seconds */\n\t\t\tsleep(5);\n\t\t}\n\n\t\tif (unlikely(!submitted)) {\n\t\t\tapplog(LOG_DEBUG, \"Failed to submit stratum share, discarding\");\n\t\t\tfree_work(work);\n\t\t\tfree(sshare);\n\t\t\tpool->stale_shares++;\n\t\t\ttotal_stale++;\n\t\t}\n\t\tgoto out;\n\t}\n\n\tce = pop_curl_entry(pool);\n\t/* submit solution to bitcoin via JSON-RPC */\n\twhile (!submit_upstream_work(work, ce->curl, resubmit)) {\n\t\tresubmit = true;\n\t\tif (stale_work(work, true)) {\n\t\t\tapplog(LOG_NOTICE, \"Pool %d share became stale while retrying submit, discarding\", pool->pool_no);\n\n\t\t\tmutex_lock(&stats_lock);\n\t\t\ttotal_stale++;\n\t\t\tpool->stale_shares++;\n\t\t\ttotal_diff_stale += work->work_difficulty;\n\t\t\tpool->diff_stale += work->work_difficulty;\n\t\t\tmutex_unlock(&stats_lock);\n\n\t\t\tbreak;\n\t\t}\n\n\t\t/* pause, then restart work-request loop */\n\t\tapplog(LOG_INFO, \"json_rpc_call failed on submit_work, retrying\");\n\t}\n\tpush_curl_entry(ce, pool);\nout:\n\treturn NULL;\n}\n\n/* Find the pool that currently has the highest priority */\nstatic struct pool *priority_pool(int choice)\n{\n\tstruct pool *ret = NULL;\n\tint i;\n\n\tfor (i = 0; i < total_pools; i++) {\n\t\tstruct pool *pool = pools[i];\n\n\t\tif (pool->prio == choice) {\n\t\t\tret = pool;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (unlikely(!ret)) {\n\t\tapplog(LOG_ERR, \"WTF No pool %d found!\", choice);\n\t\treturn pools[choice];\n\t}\n\treturn ret;\n}\n\nstatic void clear_pool_work(struct pool *pool);\n\n/* Specifies whether we can switch to this pool or not. */\nstatic bool pool_unusable(struct pool *pool)\n{\n\tif (pool->idle)\n\t\treturn true;\n\tif (pool->enabled != POOL_ENABLED)\n\t\treturn true;\n\treturn false;\n}\n\nvoid switch_pools(struct pool *selected)\n{\n\tstruct pool *pool, *last_pool;\n\tint i, pool_no, next_pool;\n\n\tcg_wlock(&control_lock);\n\tlast_pool = currentpool;\n\tpool_no = currentpool->pool_no;\n\n\t/* Switch selected to pool number 0 and move the rest down */\n\tif (selected) {\n\t\tif (selected->prio != 0) {\n\t\t\tfor (i = 0; i < total_pools; i++) {\n\t\t\t\tpool = pools[i];\n\t\t\t\tif (pool->prio < selected->prio)\n\t\t\t\t\tpool->prio++;\n\t\t\t}\n\t\t\tselected->prio = 0;\n\t\t}\n\t}\n\n\tswitch (pool_strategy) {\n\t\t/* Both of these set to the master pool */\n\t\tcase POOL_BALANCE:\n\t\tcase POOL_FAILOVER:\n\t\tcase POOL_LOADBALANCE:\n\t\t\tfor (i = 0; i < total_pools; i++) {\n\t\t\t\tpool = priority_pool(i);\n\t\t\t\tif (pool_unusable(pool))\n\t\t\t\t\tcontinue;\n\t\t\t\tpool_no = pool->pool_no;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\t/* Both of these simply increment and cycle */\n\t\tcase POOL_ROUNDROBIN:\n\t\tcase POOL_ROTATE:\n\t\t\tif (selected && !selected->idle) {\n\t\t\t\tpool_no = selected->pool_no;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tnext_pool = pool_no;\n\t\t\t/* Select the next alive pool */\n\t\t\tfor (i = 1; i < total_pools; i++) {\n\t\t\t\tnext_pool++;\n\t\t\t\tif (next_pool >= total_pools)\n\t\t\t\t\tnext_pool = 0;\n\t\t\t\tpool = pools[next_pool];\n\t\t\t\tif (pool_unusable(pool))\n\t\t\t\t\tcontinue;\n\t\t\t\tpool_no = next_pool;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\tcurrentpool = pools[pool_no];\n\tpool = currentpool;\n\tcg_wunlock(&control_lock);\n\n\t/* Set the lagging flag to avoid pool not providing work fast enough\n\t * messages in failover only mode since  we have to get all fresh work\n\t * as in restart_threads */\n\tif (opt_fail_only)\n\t\tpool_tset(pool, &pool->lagging);\n\n\tif (pool != last_pool && pool_strategy != POOL_LOADBALANCE && pool_strategy != POOL_BALANCE) {\n\t\tapplog(LOG_WARNING, \"Switching to pool %d %s\", pool->pool_no, pool->rpc_url);\n\t\tif (pool->has_gbt || pool->has_stratum || opt_fail_only)\n\t\t\tclear_pool_work(last_pool);\n\t}\n\n\tmutex_lock(&lp_lock);\n\tpthread_cond_broadcast(&lp_cond);\n\tmutex_unlock(&lp_lock);\n\n}\n\nvoid discard_work(struct work *work)\n{\n\tif (!work->clone && !work->rolls && !work->mined) {\n\t\tif (work->pool)\n\t\t\twork->pool->discarded_work++;\n\t\ttotal_discarded++;\n\t\tapplog(LOG_DEBUG, \"Discarded work\");\n\t} else\n\t\tapplog(LOG_DEBUG, \"Discarded cloned or rolled work\");\n\tfree_work(work);\n}\n\nstatic void wake_gws(void)\n{\n\tmutex_lock(stgd_lock);\n\tpthread_cond_signal(&gws_cond);\n\tmutex_unlock(stgd_lock);\n}\n\nstatic void discard_stale(void)\n{\n\tstruct work *work, *tmp;\n\tint stale = 0;\n\n\tmutex_lock(stgd_lock);\n\tHASH_ITER(hh, staged_work, work, tmp) {\n\t\tif (stale_work(work, false)) {\n\t\t\tHASH_DEL(staged_work, work);\n\t\t\tdiscard_work(work);\n\t\t\tstale++;\n\t\t}\n\t}\n\tpthread_cond_signal(&gws_cond);\n\tmutex_unlock(stgd_lock);\n\n\tif (stale)\n\t\tapplog(LOG_DEBUG, \"Discarded %d stales that didn't match current hash\", stale);\n}\n\n/* A generic wait function for threads that poll that will wait a specified\n * time tdiff waiting on the pthread conditional that is broadcast when a\n * work restart is required. Returns the value of pthread_cond_timedwait\n * which is zero if the condition was met or ETIMEDOUT if not.\n */\nint restart_wait(unsigned int mstime)\n{\n\tstruct timeval now, then, tdiff;\n\tstruct timespec abstime;\n\tint rc;\n\n\ttdiff.tv_sec = mstime / 1000;\n\ttdiff.tv_usec = mstime * 1000 - (tdiff.tv_sec * 1000000);\n\tcgtime(&now);\n\ttimeradd(&now, &tdiff, &then);\n\tabstime.tv_sec = then.tv_sec;\n\tabstime.tv_nsec = then.tv_usec * 1000;\n\n\tmutex_lock(&restart_lock);\n\trc = pthread_cond_timedwait(&restart_cond, &restart_lock, &abstime);\n\tmutex_unlock(&restart_lock);\n\n\treturn rc;\n}\n\t\nstatic void restart_threads(void)\n{\n\tstruct pool *cp = current_pool();\n\tint i;\n\n\t/* Artificially set the lagging flag to avoid pool not providing work\n\t * fast enough  messages after every long poll */\n\tpool_tset(cp, &cp->lagging);\n\n\t/* Discard staged work that is now stale */\n\tdiscard_stale();\n\n\trd_lock(&mining_thr_lock);\n\tfor (i = 0; i < mining_threads; i++)\n\t\tmining_thr[i]->work_restart = true;\n\trd_unlock(&mining_thr_lock);\n\n\tmutex_lock(&restart_lock);\n\tpthread_cond_broadcast(&restart_cond);\n\tmutex_unlock(&restart_lock);\n}\n\nstatic void set_curblock(char *hexstr, unsigned char *hash)\n{\n\tunsigned char hash_swap[32];\n\tunsigned char block_hash_swap[32];\n\n\tstrcpy(current_block, hexstr);\n\tswap256(hash_swap, hash);\n\tswap256(block_hash_swap, hash + 4);\n\n\tcg_wlock(&ch_lock);\n\tcgtime(&block_timeval);\n\tfree(current_hash);\n\tcurrent_hash = bin2hex(hash_swap + 2, 8);\n\tfree(current_fullhash);\n\tcurrent_fullhash = bin2hex(block_hash_swap, 32);\n\tget_timestamp(blocktime, &block_timeval);\n\tcg_wunlock(&ch_lock);\n\n\tapplog(LOG_INFO, \"New block: %s... diff %s\", current_hash, block_diff);\n}\n\n/* Search to see if this string is from a block that has been seen before */\nstatic bool block_exists(char *hexstr)\n{\n\tstruct block *s;\n\n\trd_lock(&blk_lock);\n\tHASH_FIND_STR(blocks, hexstr, s);\n\trd_unlock(&blk_lock);\n\n\tif (s)\n\t\treturn true;\n\treturn false;\n}\n\n/* Tests if this work is from a block that has been seen before */\nstatic inline bool from_existing_block(struct work *work)\n{\n\tchar *hexstr = bin2hex(work->data + 8, 18);\n\tbool ret;\n\n\tret = block_exists(hexstr);\n\tfree(hexstr);\n\treturn ret;\n}\n\nstatic int block_sort(struct block *blocka, struct block *blockb)\n{\n\treturn blocka->block_no - blockb->block_no;\n}\n\nstatic void set_blockdiff(const struct work *work)\n{\n\tuint64_t *data64, d64, diff64;\n\tdouble previous_diff;\n\tuint32_t diffhash[8];\n\tuint32_t difficulty;\n\tuint32_t diffbytes;\n\tuint32_t diffvalue;\n\tchar rhash[32];\n\tint diffshift;\n\n\tdifficulty = swab32(*((uint32_t *)(work->data + 72)));\n\n\tdiffbytes = ((difficulty >> 24) & 0xff) - 3;\n\tdiffvalue = difficulty & 0x00ffffff;\n\n\tdiffshift = (diffbytes % 4) * 8;\n\tif (diffshift == 0) {\n\t\tdiffshift = 32;\n\t\tdiffbytes--;\n\t}\n\n\tmemset(diffhash, 0, 32);\n\tdiffbytes >>= 2;\n\tif (unlikely(diffbytes > 6))\n\t\treturn;\n\tdiffhash[diffbytes + 1] = diffvalue >> (32 - diffshift);\n\tdiffhash[diffbytes] = diffvalue << diffshift;\n\n\tswab256(rhash, diffhash);\n\n\tif (opt_scrypt)\n\t\tdata64 = (uint64_t *)(rhash + 2);\n\telse\n\t\tdata64 = (uint64_t *)(rhash + 4);\n\td64 = be64toh(*data64);\n\tif (unlikely(!d64))\n\t\td64 = 1;\n\n\tprevious_diff = current_diff;\n\tdiff64 = diffone / d64;\n\tsuffix_string(diff64, block_diff, 0);\n\tcurrent_diff = (double)diffone / (double)d64;\n\tif (unlikely(current_diff != previous_diff))\n\t\tapplog(LOG_NOTICE, \"Network diff set to %s\", block_diff);\n}\n\nstatic bool test_work_current(struct work *work)\n{\n\tbool ret = true;\n\tchar *hexstr;\n\n\tif (work->mandatory)\n\t\treturn ret;\n\n\t/* Hack to work around dud work sneaking into test */\n\thexstr = bin2hex(work->data + 8, 18);\n\tif (!strncmp(hexstr, \"000000000000000000000000000000000000\", 36))\n\t\tgoto out_free;\n\n\t/* Search to see if this block exists yet and if not, consider it a\n\t * new block and set the current block details to this one */\n\tif (!block_exists(hexstr)) {\n\t\tstruct block *s = calloc(sizeof(struct block), 1);\n\t\tint deleted_block = 0;\n\t\tret = false;\n\n\t\tif (unlikely(!s))\n\t\t\tquit (1, \"test_work_current OOM\");\n\t\tstrcpy(s->hash, hexstr);\n\t\ts->block_no = new_blocks++;\n\n\t\twr_lock(&blk_lock);\n\t\t/* Only keep the last hour's worth of blocks in memory since\n\t\t * work from blocks before this is virtually impossible and we\n\t\t * want to prevent memory usage from continually rising */\n\t\tif (HASH_COUNT(blocks) > 6) {\n\t\t\tstruct block *oldblock;\n\n\t\t\tHASH_SORT(blocks, block_sort);\n\t\t\toldblock = blocks;\n\t\t\tdeleted_block = oldblock->block_no;\n\t\t\tHASH_DEL(blocks, oldblock);\n\t\t\tfree(oldblock);\n\t\t}\n\t\tHASH_ADD_STR(blocks, hash, s);\n\t\tset_blockdiff(work);\n\t\twr_unlock(&blk_lock);\n\n\t\tif (deleted_block)\n\t\t\tapplog(LOG_DEBUG, \"Deleted block %d from database\", deleted_block);\n\t\tset_curblock(hexstr, work->data);\n\t\tif (unlikely(new_blocks == 1))\n\t\t\tgoto out_free;\n\n\t\twork->work_block = ++work_block;\n\n\t\tif (!work->stratum) {\n\t\t\tif (work->longpoll) {\n\t\t\t\tapplog(LOG_NOTICE, \"%sLONGPOLL from pool %d detected new block\",\n\t\t\t\t       work->gbt ? \"GBT \" : \"\", work->pool->pool_no);\n\t\t\t} else if (have_longpoll)\n\t\t\t\tapplog(LOG_NOTICE, \"New block detected on network before longpoll\");\n\t\t\telse\n\t\t\t\tapplog(LOG_NOTICE, \"New block detected on network\");\n\t\t}\n\t\trestart_threads();\n\t} else if (work->longpoll) {\n\t\twork->work_block = ++work_block;\n\t\tif (work->pool == current_pool()) {\n\t\t\tapplog(LOG_NOTICE, \"%sLONGPOLL from pool %d requested work restart\",\n\t\t\t       work->gbt ? \"GBT \" : \"\", work->pool->pool_no);\n\t\t\trestart_threads();\n\t\t}\n\t}\n\twork->longpoll = false;\nout_free:\n\tfree(hexstr);\n\treturn ret;\n}\n\nstatic int tv_sort(struct work *worka, struct work *workb)\n{\n\treturn worka->tv_staged.tv_sec - workb->tv_staged.tv_sec;\n}\n\nstatic bool work_rollable(struct work *work)\n{\n\treturn (!work->clone && work->rolltime);\n}\n\nstatic bool hash_push(struct work *work)\n{\n\tbool rc = true;\n\n\tmutex_lock(stgd_lock);\n\tif (work_rollable(work))\n\t\tstaged_rollable++;\n\tif (likely(!getq->frozen)) {\n\t\tHASH_ADD_INT(staged_work, id, work);\n\t\tHASH_SORT(staged_work, tv_sort);\n\t} else\n\t\trc = false;\n\tpthread_cond_broadcast(&getq->cond);\n\tmutex_unlock(stgd_lock);\n\n\treturn rc;\n}\n\nstatic void *stage_thread(void *userdata)\n{\n\tstruct thr_info *mythr = userdata;\n\tbool ok = true;\n\n\tpthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);\n\n\tRenameThread(\"stage\");\n\n\twhile (ok) {\n\t\tstruct work *work = NULL;\n\n\t\tapplog(LOG_DEBUG, \"Popping work to stage thread\");\n\n\t\twork = tq_pop(mythr->q, NULL);\n\t\tif (unlikely(!work)) {\n\t\t\tapplog(LOG_ERR, \"Failed to tq_pop in stage_thread\");\n\t\t\tok = false;\n\t\t\tbreak;\n\t\t}\n\t\twork->work_block = work_block;\n\n\t\ttest_work_current(work);\n\n\t\tapplog(LOG_DEBUG, \"Pushing work to getwork queue\");\n\n\t\tif (unlikely(!hash_push(work))) {\n\t\t\tapplog(LOG_WARNING, \"Failed to hash_push in stage_thread\");\n\t\t\tcontinue;\n\t\t}\n\t}\n\n\ttq_freeze(mythr->q);\n\treturn NULL;\n}\n\nstatic void stage_work(struct work *work)\n{\n\tapplog(LOG_DEBUG, \"Pushing work from pool %d to hash queue\", work->pool->pool_no);\n\twork->work_block = work_block;\n\ttest_work_current(work);\n\thash_push(work);\n}\n\n#ifdef HAVE_CURSES\nint curses_int(const char *query)\n{\n\tint ret;\n\tchar *cvar;\n\n\tcvar = curses_input(query);\n\tret = atoi(cvar);\n\tfree(cvar);\n\treturn ret;\n}\n#endif\n\n#ifdef HAVE_CURSES\nstatic bool input_pool(bool live);\n#endif\n\n#ifdef HAVE_CURSES\nstatic void display_pool_summary(struct pool *pool)\n{\n\tdouble efficiency = 0.0;\n\n\tif (curses_active_locked()) {\n\t\twlog(\"Pool: %s\\n\", pool->rpc_url);\n\t\tif (pool->solved)\n\t\t\twlog(\"SOLVED %d BLOCK%s!\\n\", pool->solved, pool->solved > 1 ? \"S\" : \"\");\n\t\twlog(\"%s own long-poll support\\n\", pool->hdr_path ? \"Has\" : \"Does not have\");\n\t\twlog(\" Queued work requests: %d\\n\", pool->getwork_requested);\n\t\twlog(\" Share submissions: %d\\n\", pool->accepted + pool->rejected);\n\t\twlog(\" Accepted shares: %d\\n\", pool->accepted);\n\t\twlog(\" Rejected shares: %d\\n\", pool->rejected);\n\t\twlog(\" Accepted difficulty shares: %1.f\\n\", pool->diff_accepted);\n\t\twlog(\" Rejected difficulty shares: %1.f\\n\", pool->diff_rejected);\n\t\tif (pool->accepted || pool->rejected)\n\t\t\twlog(\" Reject ratio: %.1f%%\\n\", (double)(pool->rejected * 100) / (double)(pool->accepted + pool->rejected));\n\t\tefficiency = pool->getwork_requested ? pool->accepted * 100.0 / pool->getwork_requested : 0.0;\n\t\twlog(\" Efficiency (accepted / queued): %.0f%%\\n\", efficiency);\n\n\t\twlog(\" Discarded work due to new blocks: %d\\n\", pool->discarded_work);\n\t\twlog(\" Stale submissions discarded due to new blocks: %d\\n\", pool->stale_shares);\n\t\twlog(\" Unable to get work from server occasions: %d\\n\", pool->getfail_occasions);\n\t\twlog(\" Submitting work remotely delay occasions: %d\\n\\n\", pool->remotefail_occasions);\n\t\tunlock_curses();\n\t}\n}\n#endif\n\n/* We can't remove the memory used for this struct pool because there may\n * still be work referencing it. We just remove it from the pools list */\nvoid remove_pool(struct pool *pool)\n{\n\tint i, last_pool = total_pools - 1;\n\tstruct pool *other;\n\n\t/* Boost priority of any lower prio than this one */\n\tfor (i = 0; i < total_pools; i++) {\n\t\tother = pools[i];\n\t\tif (other->prio > pool->prio)\n\t\t\tother->prio--;\n\t}\n\n\tif (pool->pool_no < last_pool) {\n\t\t/* Swap the last pool for this one */\n\t\t(pools[last_pool])->pool_no = pool->pool_no;\n\t\tpools[pool->pool_no] = pools[last_pool];\n\t}\n\t/* Give it an invalid number */\n\tpool->pool_no = total_pools;\n\tpool->removed = true;\n\ttotal_pools--;\n}\n\n/* add a mutex if this needs to be thread safe in the future */\nstatic struct JE {\n\tchar *buf;\n\tstruct JE *next;\n} *jedata = NULL;\n\nstatic void json_escape_free()\n{\n\tstruct JE *jeptr = jedata;\n\tstruct JE *jenext;\n\n\tjedata = NULL;\n\n\twhile (jeptr) {\n\t\tjenext = jeptr->next;\n\t\tfree(jeptr->buf);\n\t\tfree(jeptr);\n\t\tjeptr = jenext;\n\t}\n}\n\nstatic char *json_escape(char *str)\n{\n\tstruct JE *jeptr;\n\tchar *buf, *ptr;\n\n\t/* 2x is the max, may as well just allocate that */\n\tptr = buf = malloc(strlen(str) * 2 + 1);\n\n\tjeptr = malloc(sizeof(*jeptr));\n\n\tjeptr->buf = buf;\n\tjeptr->next = jedata;\n\tjedata = jeptr;\n\n\twhile (*str) {\n\t\tif (*str == '\\\\' || *str == '\"')\n\t\t\t*(ptr++) = '\\\\';\n\n\t\t*(ptr++) = *(str++);\n\t}\n\n\t*ptr = '\\0';\n\n\treturn buf;\n}\n\nvoid write_config(FILE *fcfg)\n{\n\tint i;\n\n\t/* Write pool values */\n\tfputs(\"{\\n\\\"pools\\\" : [\", fcfg);\n\tfor(i = 0; i < total_pools; i++) {\n\t\tfprintf(fcfg, \"%s\\n\\t{\\n\\t\\t\\\"url\\\" : \\\"%s%s%s%s\\\",\", i > 0 ? \",\" : \"\",\n\t\t\tpools[i]->rpc_proxy ? json_escape((char *)proxytype(pools[i]->rpc_proxytype)) : \"\",\n\t\t\tpools[i]->rpc_proxy ? json_escape(pools[i]->rpc_proxy) : \"\",\n\t\t\tpools[i]->rpc_proxy ? \"|\" : \"\",\n\t\t\tjson_escape(pools[i]->rpc_url));\n\t\tfprintf(fcfg, \"\\n\\t\\t\\\"user\\\" : \\\"%s\\\",\", json_escape(pools[i]->rpc_user));\n\t\tfprintf(fcfg, \"\\n\\t\\t\\\"pass\\\" : \\\"%s\\\"\\n\\t}\", json_escape(pools[i]->rpc_pass));\n\t\t}\n\tfputs(\"\\n]\\n\", fcfg);\n\n#ifdef HAVE_OPENCL\n\tif (nDevs) {\n\t\t/* Write GPU device values */\n\t\tfputs(\",\\n\\\"intensity\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, gpus[i].dynamic ? \"%sd\" : \"%s%d\", i > 0 ? \",\" : \"\", gpus[i].intensity);\n\t\tfputs(\"\\\",\\n\\\"vectors\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%d\", i > 0 ? \",\" : \"\",\n\t\t\t\tgpus[i].vwidth);\n\t\tfputs(\"\\\",\\n\\\"worksize\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%d\", i > 0 ? \",\" : \"\",\n\t\t\t\t(int)gpus[i].work_size);\n\t\tfputs(\"\\\",\\n\\\"kernel\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++) {\n\t\t\tfprintf(fcfg, \"%s\", i > 0 ? \",\" : \"\");\n\t\t\tswitch (gpus[i].kernel) {\n\t\t\t\tcase KL_NONE: // Shouldn't happen\n\t\t\t\t\tbreak;\n\t\t\t\tcase KL_POCLBM:\n\t\t\t\t\tfprintf(fcfg, \"poclbm\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase KL_PHATK:\n\t\t\t\t\tfprintf(fcfg, \"phatk\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase KL_DIAKGCN:\n\t\t\t\t\tfprintf(fcfg, \"diakgcn\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase KL_DIABLO:\n\t\t\t\t\tfprintf(fcfg, \"diablo\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase KL_SCRYPT:\n\t\t\t\t\tfprintf(fcfg, \"scrypt\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n#ifdef USE_SCRYPT\n\t\tfputs(\"\\\",\\n\\\"lookup-gap\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%d\", i > 0 ? \",\" : \"\",\n\t\t\t\t(int)gpus[i].opt_lg);\n\t\tfputs(\"\\\",\\n\\\"thread-concurrency\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%d\", i > 0 ? \",\" : \"\",\n\t\t\t\t(int)gpus[i].opt_tc);\n\t\tfputs(\"\\\",\\n\\\"shaders\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%d\", i > 0 ? \",\" : \"\",\n\t\t\t\t(int)gpus[i].shaders);\n#endif\n#ifdef HAVE_ADL\n\t\tfputs(\"\\\",\\n\\\"gpu-engine\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%d-%d\", i > 0 ? \",\" : \"\", gpus[i].min_engine, gpus[i].gpu_engine);\n\t\tfputs(\"\\\",\\n\\\"gpu-fan\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%d-%d\", i > 0 ? \",\" : \"\", gpus[i].min_fan, gpus[i].gpu_fan);\n\t\tfputs(\"\\\",\\n\\\"gpu-memclock\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%d\", i > 0 ? \",\" : \"\", gpus[i].gpu_memclock);\n\t\tfputs(\"\\\",\\n\\\"gpu-memdiff\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%d\", i > 0 ? \",\" : \"\", gpus[i].gpu_memdiff);\n\t\tfputs(\"\\\",\\n\\\"gpu-powertune\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%d\", i > 0 ? \",\" : \"\", gpus[i].gpu_powertune);\n\t\tfputs(\"\\\",\\n\\\"gpu-vddc\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%1.3f\", i > 0 ? \",\" : \"\", gpus[i].gpu_vddc);\n\t\tfputs(\"\\\",\\n\\\"temp-cutoff\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%d\", i > 0 ? \",\" : \"\", gpus[i].cutofftemp);\n\t\tfputs(\"\\\",\\n\\\"temp-overheat\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%d\", i > 0 ? \",\" : \"\", gpus[i].adl.overtemp);\n\t\tfputs(\"\\\",\\n\\\"temp-target\\\" : \\\"\", fcfg);\n\t\tfor(i = 0; i < nDevs; i++)\n\t\t\tfprintf(fcfg, \"%s%d\", i > 0 ? \",\" : \"\", gpus[i].adl.targettemp);\n#endif\n\t\tfputs(\"\\\"\", fcfg);\n\t}\n#endif\n#ifdef HAVE_ADL\n\tif (opt_reorder)\n\t\tfprintf(fcfg, \",\\n\\\"gpu-reorder\\\" : true\");\n#endif\n\n\t/* Simple bool and int options */\n\tstruct opt_table *opt;\n\tfor (opt = opt_config_table; opt->type != OPT_END; opt++) {\n\t\tchar *p, *name = strdup(opt->names);\n\t\tfor (p = strtok(name, \"|\"); p; p = strtok(NULL, \"|\")) {\n\t\t\tif (p[1] != '-')\n\t\t\t\tcontinue;\n\t\t\tif (opt->type & OPT_NOARG &&\n\t\t\t   ((void *)opt->cb == (void *)opt_set_bool || (void *)opt->cb == (void *)opt_set_invbool) &&\n\t\t\t   (*(bool *)opt->u.arg == ((void *)opt->cb == (void *)opt_set_bool)))\n\t\t\t\tfprintf(fcfg, \",\\n\\\"%s\\\" : true\", p+2);\n\n\t\t\tif (opt->type & OPT_HASARG &&\n\t\t\t   ((void *)opt->cb_arg == (void *)set_int_0_to_9999 ||\n\t\t\t   (void *)opt->cb_arg == (void *)set_int_1_to_65535 ||\n\t\t\t   (void *)opt->cb_arg == (void *)set_int_0_to_10 ||\n\t\t\t   (void *)opt->cb_arg == (void *)set_int_1_to_10) && opt->desc != opt_hidden)\n\t\t\t\tfprintf(fcfg, \",\\n\\\"%s\\\" : \\\"%d\\\"\", p+2, *(int *)opt->u.arg);\n\t\t}\n\t}\n\n\t/* Special case options */\n\tfprintf(fcfg, \",\\n\\\"shares\\\" : \\\"%d\\\"\", opt_shares);\n\tif (pool_strategy == POOL_BALANCE)\n\t\tfputs(\",\\n\\\"balance\\\" : true\", fcfg);\n\tif (pool_strategy == POOL_LOADBALANCE)\n\t\tfputs(\",\\n\\\"load-balance\\\" : true\", fcfg);\n\tif (pool_strategy == POOL_ROUNDROBIN)\n\t\tfputs(\",\\n\\\"round-robin\\\" : true\", fcfg);\n\tif (pool_strategy == POOL_ROTATE)\n\t\tfprintf(fcfg, \",\\n\\\"rotate\\\" : \\\"%d\\\"\", opt_rotate_period);\n#if defined(unix)\n\tif (opt_stderr_cmd && *opt_stderr_cmd)\n\t\tfprintf(fcfg, \",\\n\\\"monitor\\\" : \\\"%s\\\"\", json_escape(opt_stderr_cmd));\n#endif // defined(unix)\n\tif (opt_kernel_path && *opt_kernel_path) {\n\t\tchar *kpath = strdup(opt_kernel_path);\n\t\tif (kpath[strlen(kpath)-1] == '/')\n\t\t\tkpath[strlen(kpath)-1] = 0;\n\t\tfprintf(fcfg, \",\\n\\\"kernel-path\\\" : \\\"%s\\\"\", json_escape(kpath));\n\t}\n\tif (schedstart.enable)\n\t\tfprintf(fcfg, \",\\n\\\"sched-time\\\" : \\\"%d:%d\\\"\", schedstart.tm.tm_hour, schedstart.tm.tm_min);\n\tif (schedstop.enable)\n\t\tfprintf(fcfg, \",\\n\\\"stop-time\\\" : \\\"%d:%d\\\"\", schedstop.tm.tm_hour, schedstop.tm.tm_min);\n\tif (opt_socks_proxy && *opt_socks_proxy)\n\t\tfprintf(fcfg, \",\\n\\\"socks-proxy\\\" : \\\"%s\\\"\", json_escape(opt_socks_proxy));\n\tif (devices_enabled) {\n\t\tfor (i = 0; i < (int)(sizeof(devices_enabled) * 8) - 1; ++i) {\n\t\t\tif (devices_enabled & (1 << i))\n\t\t\t\tfprintf(fcfg, \",\\n\\\"device\\\" : \\\"%d\\\"\", i);\n\t\t}\n\t}\n\tif (opt_removedisabled)\n\t\tfprintf(fcfg, \",\\n\\\"remove-disabled\\\" : true\");\n\tif (opt_api_allow)\n\t\tfprintf(fcfg, \",\\n\\\"api-allow\\\" : \\\"%s\\\"\", json_escape(opt_api_allow));\n\tif (strcmp(opt_api_description, PACKAGE_STRING) != 0)\n\t\tfprintf(fcfg, \",\\n\\\"api-description\\\" : \\\"%s\\\"\", json_escape(opt_api_description));\n\tif (opt_api_groups)\n\t\tfprintf(fcfg, \",\\n\\\"api-groups\\\" : \\\"%s\\\"\", json_escape(opt_api_groups));\n\tif (opt_icarus_options)\n\t\tfprintf(fcfg, \",\\n\\\"icarus-options\\\" : \\\"%s\\\"\", json_escape(opt_icarus_options));\n\tif (opt_icarus_timing)\n\t\tfprintf(fcfg, \",\\n\\\"icarus-timing\\\" : \\\"%s\\\"\", json_escape(opt_icarus_timing));\n\tif (opt_cainsmore_clock)\n\t\tfprintf(fcfg, \",\\n\\\"cainsmore-clock\\\" : \\\"%s\\\"\", json_escape(opt_cainsmore_clock));\t// KRAMBLE\n\tif (opt_ztex_clock)\n\t\tfprintf(fcfg, \",\\n\\\"ztex-clock\\\" : \\\"%s\\\"\", json_escape(opt_ztex_clock));\t// KRAMBLE\n#ifdef USE_USBUTILS\n\tif (opt_usb_select)\n\t\tfprintf(fcfg, \",\\n\\\"usb\\\" : \\\"%s\\\"\", json_escape(opt_usb_select));\n#endif\n\tfputs(\"\\n}\\n\", fcfg);\n\n\tjson_escape_free();\n}\n\nvoid zero_bestshare(void)\n{\n\tint i;\n\n\tbest_diff = 0;\n\tmemset(best_share, 0, 8);\n\tsuffix_string(best_diff, best_share, 0);\n\n\tfor (i = 0; i < total_pools; i++) {\n\t\tstruct pool *pool = pools[i];\n\t\tpool->best_diff = 0;\n\t}\n}\n\nvoid zero_stats(void)\n{\n\tint i;\n\n\tcgtime(&total_tv_start);\n\ttotal_mhashes_done = 0;\n\ttotal_getworks = 0;\n\ttotal_accepted = 0;\n\ttotal_rejected = 0;\n\thw_errors = 0;\n\ttotal_stale = 0;\n\ttotal_discarded = 0;\n\tlocal_work = 0;\n\ttotal_go = 0;\n\ttotal_ro = 0;\n\ttotal_secs = 1.0;\n\ttotal_diff1 = 0;\n\tfound_blocks = 0;\n\ttotal_diff_accepted = 0;\n\ttotal_diff_rejected = 0;\n\ttotal_diff_stale = 0;\n\n\tfor (i = 0; i < total_pools; i++) {\n\t\tstruct pool *pool = pools[i];\n\n\t\tpool->getwork_requested = 0;\n\t\tpool->accepted = 0;\n\t\tpool->rejected = 0;\n\t\tpool->stale_shares = 0;\n\t\tpool->discarded_work = 0;\n\t\tpool->getfail_occasions = 0;\n\t\tpool->remotefail_occasions = 0;\n\t\tpool->last_share_time = 0;\n\t\tpool->diff1 = 0;\n\t\tpool->diff_accepted = 0;\n\t\tpool->diff_rejected = 0;\n\t\tpool->diff_stale = 0;\n\t\tpool->last_share_diff = 0;\n\t}\n\n\tzero_bestshare();\n\n\tfor (i = 0; i < total_devices; ++i) {\n\t\tstruct cgpu_info *cgpu = get_devices(i);\n\n\t\tmutex_lock(&hash_lock);\n\t\tcgpu->total_mhashes = 0;\n\t\tcgpu->accepted = 0;\n\t\tcgpu->rejected = 0;\n\t\tcgpu->hw_errors = 0;\n\t\tcgpu->utility = 0.0;\n\t\tcgpu->last_share_pool_time = 0;\n\t\tcgpu->diff1 = 0;\n\t\tcgpu->diff_accepted = 0;\n\t\tcgpu->diff_rejected = 0;\n\t\tcgpu->last_share_diff = 0;\n\t\tmutex_unlock(&hash_lock);\n\t}\n}\n\n#ifdef HAVE_CURSES\nstatic void display_pools(void)\n{\n\tstruct pool *pool;\n\tint selected, i;\n\tchar input;\n\n\topt_loginput = true;\n\timmedok(logwin, true);\n\tclear_logwin();\nupdated:\n\tfor (i = 0; i < total_pools; i++) {\n\t\tpool = pools[i];\n\n\t\tif (pool == current_pool())\n\t\t\twattron(logwin, A_BOLD);\n\t\tif (pool->enabled != POOL_ENABLED)\n\t\t\twattron(logwin, A_DIM);\n\t\twlogprint(\"%d: \", pool->pool_no);\n\t\tswitch (pool->enabled) {\n\t\t\tcase POOL_ENABLED:\n\t\t\t\twlogprint(\"Enabled \");\n\t\t\t\tbreak;\n\t\t\tcase POOL_DISABLED:\n\t\t\t\twlogprint(\"Disabled \");\n\t\t\t\tbreak;\n\t\t\tcase POOL_REJECTING:\n\t\t\t\twlogprint(\"Rejecting \");\n\t\t\t\tbreak;\n\t\t}\n\t\twlogprint(\"%s Priority %d: %s  User:%s\\n\",\n\t\t\tpool->idle? \"Dead\" : \"Alive\",\n\t\t\tpool->prio,\n\t\t\tpool->rpc_url, pool->rpc_user);\n\t\twattroff(logwin, A_BOLD | A_DIM);\n\t}\nretry:\n\twlogprint(\"\\nCurrent pool management strategy: %s\\n\",\n\t\tstrategies[pool_strategy]);\n\tif (pool_strategy == POOL_ROTATE)\n\t\twlogprint(\"Set to rotate every %d minutes\\n\", opt_rotate_period);\n\twlogprint(\"[F]ailover only %s\\n\", opt_fail_only ? \"enabled\" : \"disabled\");\n\twlogprint(\"[A]dd pool [R]emove pool [D]isable pool [E]nable pool\\n\");\n\twlogprint(\"[C]hange management strategy [S]witch pool [I]nformation\\n\");\n\twlogprint(\"Or press any other key to continue\\n\");\n\tinput = getch();\n\n\tif (!strncasecmp(&input, \"a\", 1)) {\n\t\tinput_pool(true);\n\t\tgoto updated;\n\t} else if (!strncasecmp(&input, \"r\", 1)) {\n\t\tif (total_pools <= 1) {\n\t\t\twlogprint(\"Cannot remove last pool\");\n\t\t\tgoto retry;\n\t\t}\n\t\tselected = curses_int(\"Select pool number\");\n\t\tif (selected < 0 || selected >= total_pools) {\n\t\t\twlogprint(\"Invalid selection\\n\");\n\t\t\tgoto retry;\n\t\t}\n\t\tpool = pools[selected];\n\t\tif (pool == current_pool())\n\t\t\tswitch_pools(NULL);\n\t\tif (pool == current_pool()) {\n\t\t\twlogprint(\"Unable to remove pool due to activity\\n\");\n\t\t\tgoto retry;\n\t\t}\n\t\tdisable_pool(pool);\n\t\tremove_pool(pool);\n\t\tgoto updated;\n\t} else if (!strncasecmp(&input, \"s\", 1)) {\n\t\tselected = curses_int(\"Select pool number\");\n\t\tif (selected < 0 || selected >= total_pools) {\n\t\t\twlogprint(\"Invalid selection\\n\");\n\t\t\tgoto retry;\n\t\t}\n\t\tpool = pools[selected];\n\t\tenable_pool(pool);\n\t\tswitch_pools(pool);\n\t\tgoto updated;\n\t} else if (!strncasecmp(&input, \"d\", 1)) {\n\t\tif (enabled_pools <= 1) {\n\t\t\twlogprint(\"Cannot disable last pool\");\n\t\t\tgoto retry;\n\t\t}\n\t\tselected = curses_int(\"Select pool number\");\n\t\tif (selected < 0 || selected >= total_pools) {\n\t\t\twlogprint(\"Invalid selection\\n\");\n\t\t\tgoto retry;\n\t\t}\n\t\tpool = pools[selected];\n\t\tdisable_pool(pool);\n\t\tif (pool == current_pool())\n\t\t\tswitch_pools(NULL);\n\t\tgoto updated;\n\t} else if (!strncasecmp(&input, \"e\", 1)) {\n\t\tselected = curses_int(\"Select pool number\");\n\t\tif (selected < 0 || selected >= total_pools) {\n\t\t\twlogprint(\"Invalid selection\\n\");\n\t\t\tgoto retry;\n\t\t}\n\t\tpool = pools[selected];\n\t\tenable_pool(pool);\n\t\tif (pool->prio < current_pool()->prio)\n\t\t\tswitch_pools(pool);\n\t\tgoto updated;\n\t} else if (!strncasecmp(&input, \"c\", 1)) {\n\t\tfor (i = 0; i <= TOP_STRATEGY; i++)\n\t\t\twlogprint(\"%d: %s\\n\", i, strategies[i]);\n\t\tselected = curses_int(\"Select strategy number type\");\n\t\tif (selected < 0 || selected > TOP_STRATEGY) {\n\t\t\twlogprint(\"Invalid selection\\n\");\n\t\t\tgoto retry;\n\t\t}\n\t\tif (selected == POOL_ROTATE) {\n\t\t\topt_rotate_period = curses_int(\"Select interval in minutes\");\n\n\t\t\tif (opt_rotate_period < 0 || opt_rotate_period > 9999) {\n\t\t\t\topt_rotate_period = 0;\n\t\t\t\twlogprint(\"Invalid selection\\n\");\n\t\t\t\tgoto retry;\n\t\t\t}\n\t\t}\n\t\tpool_strategy = selected;\n\t\tswitch_pools(NULL);\n\t\tgoto updated;\n\t} else if (!strncasecmp(&input, \"i\", 1)) {\n\t\tselected = curses_int(\"Select pool number\");\n\t\tif (selected < 0 || selected >= total_pools) {\n\t\t\twlogprint(\"Invalid selection\\n\");\n\t\t\tgoto retry;\n\t\t}\n\t\tpool = pools[selected];\n\t\tdisplay_pool_summary(pool);\n\t\tgoto retry;\n\t} else if (!strncasecmp(&input, \"f\", 1)) {\n\t\topt_fail_only ^= true;\n\t\tgoto updated;\n\t} else\n\t\tclear_logwin();\n\n\timmedok(logwin, false);\n\topt_loginput = false;\n}\n\nstatic void display_options(void)\n{\n\tint selected;\n\tchar input;\n\n\topt_loginput = true;\n\timmedok(logwin, true);\n\tclear_logwin();\nretry:\n\twlogprint(\"[N]ormal [C]lear [S]ilent mode (disable all output)\\n\");\n\twlogprint(\"[D]ebug:%s\\n[P]er-device:%s\\n[Q]uiet:%s\\n[V]erbose:%s\\n\"\n\t\t  \"[R]PC debug:%s\\n[W]orkTime details:%s\\nco[M]pact: %s\\n\"\n\t\t  \"[L]og interval:%d\\n[Z]ero statistics\\n\",\n\t\topt_debug ? \"on\" : \"off\",\n\t        want_per_device_stats? \"on\" : \"off\",\n\t\topt_quiet ? \"on\" : \"off\",\n\t\topt_log_output ? \"on\" : \"off\",\n\t\topt_protocol ? \"on\" : \"off\",\n\t\topt_worktime ? \"on\" : \"off\",\n\t\topt_compact ? \"on\" : \"off\",\n\t\topt_log_interval);\n\twlogprint(\"Select an option or any other key to return\\n\");\n\tinput = getch();\n\tif (!strncasecmp(&input, \"q\", 1)) {\n\t\topt_quiet ^= true;\n\t\twlogprint(\"Quiet mode %s\\n\", opt_quiet ? \"enabled\" : \"disabled\");\n\t\tgoto retry;\n\t} else if (!strncasecmp(&input, \"v\", 1)) {\n\t\topt_log_output ^= true;\n\t\tif (opt_log_output)\n\t\t\topt_quiet = false;\n\t\twlogprint(\"Verbose mode %s\\n\", opt_log_output ? \"enabled\" : \"disabled\");\n\t\tgoto retry;\n\t} else if (!strncasecmp(&input, \"n\", 1)) {\n\t\topt_log_output = false;\n\t\topt_debug = false;\n\t\topt_quiet = false;\n\t\topt_protocol = false;\n\t\topt_compact = false;\n\t\twant_per_device_stats = false;\n\t\twlogprint(\"Output mode reset to normal\\n\");\n\t\tswitch_compact();\n\t\tgoto retry;\n\t} else if (!strncasecmp(&input, \"d\", 1)) {\n\t\topt_debug ^= true;\n\t\topt_log_output = opt_debug;\n\t\tif (opt_debug)\n\t\t\topt_quiet = false;\n\t\twlogprint(\"Debug mode %s\\n\", opt_debug ? \"enabled\" : \"disabled\");\n\t\tgoto retry;\n\t} else if (!strncasecmp(&input, \"m\", 1)) {\n\t\topt_compact ^= true;\n\t\twlogprint(\"Compact mode %s\\n\", opt_compact ? \"enabled\" : \"disabled\");\n\t\tswitch_compact();\n\t\tgoto retry;\n\t} else if (!strncasecmp(&input, \"p\", 1)) {\n\t\twant_per_device_stats ^= true;\n\t\topt_log_output = want_per_device_stats;\n\t\twlogprint(\"Per-device stats %s\\n\", want_per_device_stats ? \"enabled\" : \"disabled\");\n\t\tgoto retry;\n\t} else if (!strncasecmp(&input, \"r\", 1)) {\n\t\topt_protocol ^= true;\n\t\tif (opt_protocol)\n\t\t\topt_quiet = false;\n\t\twlogprint(\"RPC protocol debugging %s\\n\", opt_protocol ? \"enabled\" : \"disabled\");\n\t\tgoto retry;\n\t} else if (!strncasecmp(&input, \"c\", 1))\n\t\tclear_logwin();\n\telse if (!strncasecmp(&input, \"l\", 1)) {\n\t\tselected = curses_int(\"Interval in seconds\");\n\t\tif (selected < 0 || selected > 9999) {\n\t\t\twlogprint(\"Invalid selection\\n\");\n\t\t\tgoto retry;\n\t\t}\n\t\topt_log_interval = selected;\n\t\twlogprint(\"Log interval set to %d seconds\\n\", opt_log_interval);\n\t\tgoto retry;\n\t} else if (!strncasecmp(&input, \"s\", 1)) {\n\t\topt_realquiet = true;\n\t} else if (!strncasecmp(&input, \"w\", 1)) {\n\t\topt_worktime ^= true;\n\t\twlogprint(\"WorkTime details %s\\n\", opt_worktime ? \"enabled\" : \"disabled\");\n\t\tgoto retry;\n\t} else if (!strncasecmp(&input, \"z\", 1)) {\n\t\tzero_stats();\n\t\tgoto retry;\n\t} else\n\t\tclear_logwin();\n\n\timmedok(logwin, false);\n\topt_loginput = false;\n}\n#endif\n\nvoid default_save_file(char *filename)\n{\n\tif (default_config && *default_config) {\n\t\tstrcpy(filename, default_config);\n\t\treturn;\n\t}\n\n#if defined(unix)\n\tif (getenv(\"HOME\") && *getenv(\"HOME\")) {\n\t        strcpy(filename, getenv(\"HOME\"));\n\t\tstrcat(filename, \"/\");\n\t}\n\telse\n\t\tstrcpy(filename, \"\");\n\tstrcat(filename, \".cgminer/\");\n\tmkdir(filename, 0777);\n#else\n\tstrcpy(filename, \"\");\n#endif\n\tstrcat(filename, def_conf);\n}\n\n#ifdef HAVE_CURSES\nstatic void set_options(void)\n{\n\tint selected;\n\tchar input;\n\n\topt_loginput = true;\n\timmedok(logwin, true);\n\tclear_logwin();\nretry:\n\twlogprint(\"[Q]ueue: %d\\n[S]cantime: %d\\n[E]xpiry: %d\\n\"\n\t\t  \"[W]rite config file\\n[C]gminer restart\\n\",\n\t\topt_queue, opt_scantime, opt_expiry);\n\twlogprint(\"Select an option or any other key to return\\n\");\n\tinput = getch();\n\n\tif (!strncasecmp(&input, \"q\", 1)) {\n\t\tselected = curses_int(\"Extra work items to queue\");\n\t\tif (selected < 0 || selected > 9999) {\n\t\t\twlogprint(\"Invalid selection\\n\");\n\t\t\tgoto retry;\n\t\t}\n\t\topt_queue = selected;\n\t\tgoto retry;\n\t} else if  (!strncasecmp(&input, \"s\", 1)) {\n\t\tselected = curses_int(\"Set scantime in seconds\");\n\t\tif (selected < 0 || selected > 9999) {\n\t\t\twlogprint(\"Invalid selection\\n\");\n\t\t\tgoto retry;\n\t\t}\n\t\topt_scantime = selected;\n\t\tgoto retry;\n\t} else if  (!strncasecmp(&input, \"e\", 1)) {\n\t\tselected = curses_int(\"Set expiry time in seconds\");\n\t\tif (selected < 0 || selected > 9999) {\n\t\t\twlogprint(\"Invalid selection\\n\");\n\t\t\tgoto retry;\n\t\t}\n\t\topt_expiry = selected;\n\t\tgoto retry;\n\t} else if  (!strncasecmp(&input, \"w\", 1)) {\n\t\tFILE *fcfg;\n\t\tchar *str, filename[PATH_MAX], prompt[PATH_MAX + 50];\n\n\t\tdefault_save_file(filename);\n\t\tsprintf(prompt, \"Config filename to write (Enter for default) [%s]\", filename);\n\t\tstr = curses_input(prompt);\n\t\tif (strcmp(str, \"-1\")) {\n\t\t\tstruct stat statbuf;\n\n\t\t\tstrcpy(filename, str);\n\t\t\tfree(str);\n\t\t\tif (!stat(filename, &statbuf)) {\n\t\t\t\twlogprint(\"File exists, overwrite?\\n\");\n\t\t\t\tinput = getch();\n\t\t\t\tif (strncasecmp(&input, \"y\", 1))\n\t\t\t\t\tgoto retry;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tfree(str);\n\t\tfcfg = fopen(filename, \"w\");\n\t\tif (!fcfg) {\n\t\t\twlogprint(\"Cannot open or create file\\n\");\n\t\t\tgoto retry;\n\t\t}\n\t\twrite_config(fcfg);\n\t\tfclose(fcfg);\n\t\tgoto retry;\n\n\t} else if (!strncasecmp(&input, \"c\", 1)) {\n\t\twlogprint(\"Are you sure?\\n\");\n\t\tinput = getch();\n\t\tif (!strncasecmp(&input, \"y\", 1))\n\t\t\tapp_restart();\n\t\telse\n\t\t\tclear_logwin();\n\t} else\n\t\tclear_logwin();\n\n\timmedok(logwin, false);\n\topt_loginput = false;\n}\n\nstatic void *input_thread(void __maybe_unused *userdata)\n{\n\tpthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);\n\n\tRenameThread(\"input\");\n\n\tif (!curses_active)\n\t\treturn NULL;\n\n\twhile (1) {\n\t\tchar input;\n\n\t\tinput = getch();\n\t\tif (!strncasecmp(&input, \"q\", 1)) {\n\t\t\tkill_work();\n\t\t\treturn NULL;\n\t\t} else if (!strncasecmp(&input, \"d\", 1))\n\t\t\tdisplay_options();\n\t\telse if (!strncasecmp(&input, \"p\", 1))\n\t\t\tdisplay_pools();\n\t\telse if (!strncasecmp(&input, \"s\", 1))\n\t\t\tset_options();\n\t\telse if (have_opencl && !strncasecmp(&input, \"g\", 1))\n\t\t\tmanage_gpu();\n\t\tif (opt_realquiet) {\n\t\t\tdisable_curses();\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn NULL;\n}\n#endif\n\nstatic void *api_thread(void *userdata)\n{\n\tstruct thr_info *mythr = userdata;\n\n\tpthread_detach(pthread_self());\n\tpthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);\n\n\tRenameThread(\"api\");\n\n\tapi(api_thr_id);\n\n\tPTH(mythr) = 0L;\n\n\treturn NULL;\n}\n\nvoid thread_reportin(struct thr_info *thr)\n{\n\tcgtime(&thr->last);\n\tthr->cgpu->status = LIFE_WELL;\n\tthr->getwork = false;\n\tthr->cgpu->device_last_well = time(NULL);\n}\n\nstatic inline void thread_reportout(struct thr_info *thr)\n{\n\tthr->getwork = true;\n}\n\nstatic void hashmeter(int thr_id, struct timeval *diff,\n\t\t      uint64_t hashes_done)\n{\n\tstruct timeval temp_tv_end, total_diff;\n\tdouble secs;\n\tdouble local_secs;\n\tdouble utility;\n\tstatic double local_mhashes_done = 0;\n\tstatic double rolling = 0;\n\tdouble local_mhashes;\n\tbool showlog = false;\n\tchar displayed_hashes[16], displayed_rolling[16];\n\tuint64_t dh64, dr64;\n\tstruct thr_info *thr;\n\n\tlocal_mhashes = (double)hashes_done / 1000000.0;\n\t/* Update the last time this thread reported in */\n\tif (thr_id >= 0) {\n\t\tthr = get_thread(thr_id);\n\t\tcgtime(&(thr->last));\n\t\tthr->cgpu->device_last_well = time(NULL);\n\t}\n\n\tsecs = (double)diff->tv_sec + ((double)diff->tv_usec / 1000000.0);\n\n\t/* So we can call hashmeter from a non worker thread */\n\tif (thr_id >= 0) {\n\t\tstruct cgpu_info *cgpu = thr->cgpu;\n\t\tdouble thread_rolling = 0.0;\n\t\tint i;\n\n\t\tapplog(LOG_DEBUG, \"[thread %d: %\"PRIu64\" hashes, %.1f khash/sec]\",\n\t\t\tthr_id, hashes_done, hashes_done / 1000 / secs);\n\n\t\t/* Rolling average for each thread and each device */\n\t\tdecay_time(&thr->rolling, local_mhashes / secs);\n\t\tfor (i = 0; i < cgpu->threads; i++)\n\t\t\tthread_rolling += cgpu->thr[i]->rolling;\n\n\t\tmutex_lock(&hash_lock);\n\t\tdecay_time(&cgpu->rolling, thread_rolling);\n\t\tcgpu->total_mhashes += local_mhashes;\n\t\tmutex_unlock(&hash_lock);\n\n\t\t// If needed, output detailed, per-device stats\n\t\tif (want_per_device_stats) {\n\t\t\tstruct timeval now;\n\t\t\tstruct timeval elapsed;\n\n\t\t\tcgtime(&now);\n\t\t\ttimersub(&now, &thr->cgpu->last_message_tv, &elapsed);\n\t\t\tif (opt_log_interval <= elapsed.tv_sec) {\n\t\t\t\tstruct cgpu_info *cgpu = thr->cgpu;\n\t\t\t\tchar logline[255];\n\n\t\t\t\tcgpu->last_message_tv = now;\n\n\t\t\t\tget_statline(logline, cgpu);\n\t\t\t\tif (!curses_active) {\n\t\t\t\t\tprintf(\"%s          \\r\", logline);\n\t\t\t\t\tfflush(stdout);\n\t\t\t\t} else\n\t\t\t\t\tapplog(LOG_INFO, \"%s\", logline);\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Totals are updated by all threads so can race without locking */\n\tmutex_lock(&hash_lock);\n\tcgtime(&temp_tv_end);\n\ttimersub(&temp_tv_end, &total_tv_end, &total_diff);\n\n\ttotal_mhashes_done += local_mhashes;\n\tlocal_mhashes_done += local_mhashes;\n\t/* Only update with opt_log_interval */\n\tif (total_diff.tv_sec < opt_log_interval)\n\t\tgoto out_unlock;\n\tshowlog = true;\n\tcgtime(&total_tv_end);\n\n\tlocal_secs = (double)total_diff.tv_sec + ((double)total_diff.tv_usec / 1000000.0);\n\tdecay_time(&rolling, local_mhashes_done / local_secs);\n\tglobal_hashrate = roundl(rolling) * 1000000;\n\n\ttimersub(&total_tv_end, &total_tv_start, &total_diff);\n\ttotal_secs = (double)total_diff.tv_sec +\n\t\t((double)total_diff.tv_usec / 1000000.0);\n\n\tutility = total_accepted / total_secs * 60;\n\n\tdh64 = (double)total_mhashes_done / total_secs * 1000000ull;\n\tdr64 = (double)rolling * 1000000ull;\n\tsuffix_string(dh64, displayed_hashes, 4);\n\tsuffix_string(dr64, displayed_rolling, 4);\n\n\tsprintf(statusline, \"%s(%ds):%s (avg):%sh/s | A:%d  R:%d  HW:%d  U:%.1f/m  WU:%.1f/m\",\n\t\twant_per_device_stats ? \"ALL \" : \"\",\n\t\topt_log_interval, displayed_rolling, displayed_hashes,\n\t\ttotal_accepted, total_rejected, hw_errors, utility,\n\t\ttotal_diff1 / total_secs * 60);\n\n\tlocal_mhashes_done = 0;\nout_unlock:\n\tmutex_unlock(&hash_lock);\n\n\tif (showlog) {\n\t\tif (!curses_active) {\n\t\t\tprintf(\"%s          \\r\", statusline);\n\t\t\tfflush(stdout);\n\t\t} else\n\t\t\tapplog(LOG_INFO, \"%s\", statusline);\n\t}\n}\n\nstatic void stratum_share_result(json_t *val, json_t *res_val, json_t *err_val,\n\t\t\t\t struct stratum_share *sshare)\n{\n\tstruct work *work = sshare->work;\n\tchar hashshow[65];\n\tuint32_t *hash32;\n\tchar diffdisp[16];\n\tint intdiff;\n\n\thash32 = (uint32_t *)(work->hash);\n\tintdiff = floor(work->work_difficulty);\n\tsuffix_string(work->share_diff, diffdisp, 0);\n\tsprintf(hashshow, \"%08lx Diff %s/%d%s\", (unsigned long)htole32(hash32[6]), diffdisp, intdiff,\n\t\twork->block? \" BLOCK!\" : \"\");\n\tshare_result(val, res_val, err_val, work, hashshow, false, \"\");\n}\n\n/* Parses stratum json responses and tries to find the id that the request\n * matched to and treat it accordingly. */\nstatic bool parse_stratum_response(struct pool *pool, char *s)\n{\n\tjson_t *val = NULL, *err_val, *res_val, *id_val;\n\tstruct stratum_share *sshare;\n\tjson_error_t err;\n\tbool ret = false;\n\tint id;\n\n\tval = JSON_LOADS(s, &err);\n\tif (!val) {\n\t\tapplog(LOG_INFO, \"JSON decode failed(%d): %s\", err.line, err.text);\n\t\tgoto out;\n\t}\n\n\tres_val = json_object_get(val, \"result\");\n\terr_val = json_object_get(val, \"error\");\n\tid_val = json_object_get(val, \"id\");\n\n\tif (json_is_null(id_val) || !id_val) {\n\t\tchar *ss;\n\n\t\tif (err_val)\n\t\t\tss = json_dumps(err_val, JSON_INDENT(3));\n\t\telse\n\t\t\tss = strdup(\"(unknown reason)\");\n\n\t\tapplog(LOG_INFO, \"JSON-RPC non method decode failed: %s\", ss);\n\n\t\tfree(ss);\n\n\t\tgoto out;\n\t}\n\n\tid = json_integer_value(id_val);\n\n\tmutex_lock(&sshare_lock);\n\tHASH_FIND_INT(stratum_shares, &id, sshare);\n\tif (sshare) {\n\t\tHASH_DEL(stratum_shares, sshare);\n\t\tpool->sshares--;\n\t}\n\tmutex_unlock(&sshare_lock);\n\n\tif (!sshare) {\n\t\tif (json_is_true(res_val))\n\t\t\tapplog(LOG_NOTICE, \"Accepted untracked stratum share from pool %d\", pool->pool_no);\n\t\telse\n\t\t\tapplog(LOG_NOTICE, \"Rejected untracked stratum share from pool %d\", pool->pool_no);\n\t\tgoto out;\n\t}\n\tstratum_share_result(val, res_val, err_val, sshare);\n\tfree_work(sshare->work);\n\tfree(sshare);\n\n\tret = true;\nout:\n\tif (val)\n\t\tjson_decref(val);\n\n\treturn ret;\n}\n\nvoid clear_stratum_shares(struct pool *pool)\n{\n\tstruct stratum_share *sshare, *tmpshare;\n\tdouble diff_cleared = 0;\n\tint cleared = 0;\n\n\tmutex_lock(&sshare_lock);\n\tHASH_ITER(hh, stratum_shares, sshare, tmpshare) {\n\t\tif (sshare->work->pool == pool) {\n\t\t\tHASH_DEL(stratum_shares, sshare);\n\t\t\tdiff_cleared += sshare->work->work_difficulty;\n\t\t\tfree_work(sshare->work);\n\t\t\tpool->sshares--;\n\t\t\tfree(sshare);\n\t\t\tcleared++;\n\t\t}\n\t}\n\tmutex_unlock(&sshare_lock);\n\n\tif (cleared) {\n\t\tapplog(LOG_WARNING, \"Lost %d shares due to stratum disconnect on pool %d\", cleared, pool->pool_no);\n\t\tpool->stale_shares += cleared;\n\t\ttotal_stale += cleared;\n\t\tpool->diff_stale += diff_cleared;\n\t\ttotal_diff_stale += diff_cleared;\n\t}\n}\n\nstatic void clear_pool_work(struct pool *pool)\n{\n\tstruct work *work, *tmp;\n\tint cleared = 0;\n\n\tmutex_lock(stgd_lock);\n\tHASH_ITER(hh, staged_work, work, tmp) {\n\t\tif (work->pool == pool) {\n\t\t\tHASH_DEL(staged_work, work);\n\t\t\tfree_work(work);\n\t\t\tcleared++;\n\t\t}\n\t}\n\tmutex_unlock(stgd_lock);\n}\n\nstatic int cp_prio(void)\n{\n\tint prio;\n\n\tcg_rlock(&control_lock);\n\tprio = currentpool->prio;\n\tcg_runlock(&control_lock);\n\n\treturn prio;\n}\n\n/* We only need to maintain a secondary pool connection when we need the\n * capacity to get work from the backup pools while still on the primary */\nstatic bool cnx_needed(struct pool *pool)\n{\n\tstruct pool *cp;\n\n\t/* Balance strategies need all pools online */\n\tif (pool_strategy == POOL_BALANCE)\n\t\treturn true;\n\tif (pool_strategy == POOL_LOADBALANCE)\n\t\treturn true;\n\n\t/* Idle stratum pool needs something to kick it alive again */\n\tif (pool->has_stratum && pool->idle)\n\t\treturn true;\n\n\t/* Getwork pools without opt_fail_only need backup pools up to be able\n\t * to leak shares */\n\tcp = current_pool();\n\tif (cp == pool)\n\t\treturn true;\n\tif (!cp->has_gbt && !cp->has_stratum && (!opt_fail_only || !cp->hdr_path))\n\t\treturn true;\n\t/* If we're waiting for a response from shares submitted, keep the\n\t * connection open. */\n\tif (pool->sshares)\n\t\treturn true;\n\t/* If the pool has only just come to life and is higher priority than\n\t * the current pool keep the connection open so we can fail back to\n\t * it. */\n\tif (pool_strategy == POOL_FAILOVER && pool->prio < cp_prio())\n\t\treturn true;\n\tif (pool_unworkable(cp))\n\t\treturn true;\n\treturn false;\n}\n\nstatic void wait_lpcurrent(struct pool *pool);\nstatic void pool_resus(struct pool *pool);\nstatic void gen_stratum_work(struct pool *pool, struct work *work);\n\nstatic void stratum_resumed(struct pool *pool)\n{\n\tif (!pool->stratum_notify)\n\t\treturn;\n\tif (pool_tclear(pool, &pool->idle)) {\n\t\tapplog(LOG_INFO, \"Stratum connection to pool %d resumed\", pool->pool_no);\n\t\tpool_resus(pool);\n\t}\n}\n\nstatic bool supports_resume(struct pool *pool)\n{\n\tbool ret;\n\n\tcg_rlock(&pool->data_lock);\n\tret = (pool->sessionid != NULL);\n\tcg_runlock(&pool->data_lock);\n\n\treturn ret;\n}\n\n/* One stratum thread per pool that has stratum waits on the socket checking\n * for new messages and for the integrity of the socket connection. We reset\n * the connection based on the integrity of the receive side only as the send\n * side will eventually expire data it fails to send. */\nstatic void *stratum_thread(void *userdata)\n{\n\tstruct pool *pool = (struct pool *)userdata;\n\tchar threadname[16];\n\n\tpthread_detach(pthread_self());\n\n\tsnprintf(threadname, 16, \"stratum/%d\", pool->pool_no);\n\tRenameThread(threadname);\n\n\twhile (42) {\n\t\tstruct timeval timeout;\n\t\tint sel_ret;\n\t\tfd_set rd;\n\t\tchar *s;\n\n\t\tif (unlikely(pool->removed))\n\t\t\tbreak;\n\n\t\t/* Check to see whether we need to maintain this connection\n\t\t * indefinitely or just bring it up when we switch to this\n\t\t * pool */\n\t\tif (!sock_full(pool) && !cnx_needed(pool)) {\n\t\t\tsuspend_stratum(pool);\n\t\t\tclear_stratum_shares(pool);\n\t\t\tclear_pool_work(pool);\n\n\t\t\twait_lpcurrent(pool);\n\t\t\tif (!restart_stratum(pool)) {\n\t\t\t\tpool_died(pool);\n\t\t\t\twhile (!restart_stratum(pool)) {\n\t\t\t\t\tif (pool->removed)\n\t\t\t\t\t\tgoto out;\n\t\t\t\t\tnmsleep(30000);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tFD_ZERO(&rd);\n\t\tFD_SET(pool->sock, &rd);\n\t\ttimeout.tv_sec = 90;\n\t\ttimeout.tv_usec = 0;\n\n\t\t/* The protocol specifies that notify messages should be sent\n\t\t * every minute so if we fail to receive any for 90 seconds we\n\t\t * assume the connection has been dropped and treat this pool\n\t\t * as dead */\n\t\tif (!sock_full(pool) && (sel_ret = select(pool->sock + 1, &rd, NULL, NULL, &timeout)) < 1) {\n\t\t\tapplog(LOG_DEBUG, \"Stratum select failed on pool %d with value %d\", pool->pool_no, sel_ret);\n\t\t\ts = NULL;\n\t\t} else\n\t\t\ts = recv_line(pool);\n\t\tif (!s) {\n\t\t\tapplog(LOG_NOTICE, \"Stratum connection to pool %d interrupted\", pool->pool_no);\n\t\t\tpool->getfail_occasions++;\n\t\t\ttotal_go++;\n\n\t\t\t/* If the socket to our stratum pool disconnects, all\n\t\t\t * tracked submitted shares are lost and we will leak\n\t\t\t * the memory if we don't discard their records. */\n\t\t\tif (!supports_resume(pool))\n\t\t\t\tclear_stratum_shares(pool);\n\t\t\tclear_pool_work(pool);\n\t\t\tif (pool == current_pool())\n\t\t\t\trestart_threads();\n\n\t\t\tif (restart_stratum(pool))\n\t\t\t\tcontinue;\n\n\t\t\tpool_died(pool);\n\t\t\twhile (!restart_stratum(pool)) {\n\t\t\t\tif (pool->removed)\n\t\t\t\t\tgoto out;\n\t\t\t\tnmsleep(30000);\n\t\t\t}\n\t\t\tstratum_resumed(pool);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Check this pool hasn't died while being a backup pool and\n\t\t * has not had its idle flag cleared */\n\t\tstratum_resumed(pool);\n\n\t\tif (!parse_method(pool, s) && !parse_stratum_response(pool, s))\n\t\t\tapplog(LOG_INFO, \"Unknown stratum msg: %s\", s);\n\t\tfree(s);\n\t\tif (pool->swork.clean) {\n\t\t\tstruct work *work = make_work();\n\n\t\t\t/* Generate a single work item to update the current\n\t\t\t * block database */\n\t\t\tpool->swork.clean = false;\n\t\t\tgen_stratum_work(pool, work);\n\t\t\tif (test_work_current(work)) {\n\t\t\t\t/* Only accept a work restart if this stratum\n\t\t\t\t * connection is from the current pool */\n\t\t\t\tif (pool == current_pool()) {\n\t\t\t\t\trestart_threads();\n\t\t\t\t\tapplog(LOG_NOTICE, \"Stratum from pool %d requested work restart\", pool->pool_no);\n\t\t\t\t}\n\t\t\t} else\n\t\t\t\tapplog(LOG_NOTICE, \"Stratum from pool %d detected new block\", pool->pool_no);\n\t\t\tfree_work(work);\n\t\t}\n\t}\n\nout:\n\treturn NULL;\n}\n\nstatic void init_stratum_thread(struct pool *pool)\n{\n\tif (unlikely(pthread_create(&pool->stratum_thread, NULL, stratum_thread, (void *)pool)))\n\t\tquit(1, \"Failed to create stratum thread\");\n}\n\nstatic void *longpoll_thread(void *userdata);\n\nstatic bool stratum_works(struct pool *pool)\n{\n\tapplog(LOG_INFO, \"Testing pool %d stratum %s\", pool->pool_no, pool->stratum_url);\n\tif (!extract_sockaddr(pool, pool->stratum_url))\n\t\treturn false;\n\n\tif (!initiate_stratum(pool))\n\t\treturn false;\n\n\treturn true;\n}\n\nstatic bool pool_active(struct pool *pool, bool pinging)\n{\n\tstruct timeval tv_getwork, tv_getwork_reply;\n\tbool ret = false;\n\tjson_t *val;\n\tCURL *curl;\n\tint rolltime;\n\n\tif (pool->has_gbt)\n\t\tapplog(LOG_DEBUG, \"Retrieving block template from pool %s\", pool->rpc_url);\n\telse\n\t\tapplog(LOG_INFO, \"Testing pool %s\", pool->rpc_url);\n\n\t/* This is the central point we activate stratum when we can */\nretry_stratum:\n\tif (pool->has_stratum) {\n\t\t/* We create the stratum thread for each pool just after\n\t\t * successful authorisation. Once the init flag has been set\n\t\t * we never unset it and the stratum thread is responsible for\n\t\t * setting/unsetting the active flag */\n\t\tbool init = pool_tset(pool, &pool->stratum_init);\n\n\t\tif (!init) {\n\t\t\tbool ret = initiate_stratum(pool) && auth_stratum(pool);\n\n\t\t\tif (ret)\n\t\t\t\tinit_stratum_thread(pool);\n\t\t\telse\n\t\t\t\tpool_tclear(pool, &pool->stratum_init);\n\t\t\treturn ret;\n\t\t}\n\t\treturn pool->stratum_active;\n\t}\n\n\tcurl = curl_easy_init();\n\tif (unlikely(!curl)) {\n\t\tapplog(LOG_ERR, \"CURL initialisation failed\");\n\t\treturn false;\n\t}\n\n\t/* Probe for GBT support on first pass */\n\tif (!pool->probed && !opt_fix_protocol) {\n\t\tapplog(LOG_DEBUG, \"Probing for GBT support\");\n\t\tval = json_rpc_call(curl, pool->rpc_url, pool->rpc_userpass,\n\t\t\t\t    gbt_req, true, false, &rolltime, pool, false);\n\t\tif (val) {\n\t\t\tbool append = false, submit = false;\n\t\t\tjson_t *res_val, *mutables;\n\t\t\tint i, mutsize = 0;\n\n\t\t\tres_val = json_object_get(val, \"result\");\n\t\t\tif (res_val) {\n\t\t\t\tmutables = json_object_get(res_val, \"mutable\");\n\t\t\t\tmutsize = json_array_size(mutables);\n\t\t\t}\n\n\t\t\tfor (i = 0; i < mutsize; i++) {\n\t\t\t\tjson_t *arrval = json_array_get(mutables, i);\n\n\t\t\t\tif (json_is_string(arrval)) {\n\t\t\t\t\tconst char *mutable = json_string_value(arrval);\n\n\t\t\t\t\tif (!strncasecmp(mutable, \"coinbase/append\", 15))\n\t\t\t\t\t\tappend = true;\n\t\t\t\t\telse if (!strncasecmp(mutable, \"submit/coinbase\", 15))\n\t\t\t\t\t\tsubmit = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tjson_decref(val);\n\n\t\t\t/* Only use GBT if it supports coinbase append and\n\t\t\t * submit coinbase */\n\t\t\tif (append && submit) {\n\t\t\t\tpool->has_gbt = true;\n\t\t\t\tpool->rpc_req = gbt_req;\n\t\t\t}\n\t\t}\n\t\t/* Reset this so we can probe fully just after this. It will be\n\t\t * set to true that time.*/\n\t\tpool->probed = false;\n\n\t\tif (pool->has_gbt)\n\t\t\tapplog(LOG_DEBUG, \"GBT coinbase + append support found, switching to GBT protocol\");\n\t\telse\n\t\t\tapplog(LOG_DEBUG, \"No GBT coinbase + append support found, using getwork protocol\");\n\t}\n\n\tcgtime(&tv_getwork);\n\tval = json_rpc_call(curl, pool->rpc_url, pool->rpc_userpass,\n\t\t\t    pool->rpc_req, true, false, &rolltime, pool, false);\n\tcgtime(&tv_getwork_reply);\n\n\t/* Detect if a http getwork pool has an X-Stratum header at startup,\n\t * and if so, switch to that in preference to getwork if it works */\n\tif (pool->stratum_url && !opt_fix_protocol && stratum_works(pool)) {\n\t\tapplog(LOG_NOTICE, \"Switching pool %d %s to %s\", pool->pool_no, pool->rpc_url, pool->stratum_url);\n\t\tif (!pool->rpc_url)\n\t\t\tpool->rpc_url = strdup(pool->stratum_url);\n\t\tpool->has_stratum = true;\n\t\tcurl_easy_cleanup(curl);\n\n\t\tgoto retry_stratum;\n\t}\n\n\tif (val) {\n\t\tstruct work *work = make_work();\n\t\tbool rc;\n\n\t\trc = work_decode(pool, work, val);\n\t\tif (rc) {\n\t\t\tapplog(LOG_DEBUG, \"Successfully retrieved and deciphered work from pool %u %s\",\n\t\t\t       pool->pool_no, pool->rpc_url);\n\t\t\twork->pool = pool;\n\t\t\twork->rolltime = rolltime;\n\t\t\tcopy_time(&work->tv_getwork, &tv_getwork);\n\t\t\tcopy_time(&work->tv_getwork_reply, &tv_getwork_reply);\n\t\t\twork->getwork_mode = GETWORK_MODE_TESTPOOL;\n\t\t\tcalc_diff(work, 0);\n\t\t\tapplog(LOG_DEBUG, \"Pushing pooltest work to base pool\");\n\n\t\t\ttq_push(control_thr[stage_thr_id].q, work);\n\t\t\ttotal_getworks++;\n\t\t\tpool->getwork_requested++;\n\t\t\tret = true;\n\t\t\tcgtime(&pool->tv_idle);\n\t\t} else {\n\t\t\tapplog(LOG_DEBUG, \"Successfully retrieved but FAILED to decipher work from pool %u %s\",\n\t\t\t       pool->pool_no, pool->rpc_url);\n\t\t\tfree_work(work);\n\t\t}\n\t\tjson_decref(val);\n\n\t\tif (pool->lp_url)\n\t\t\tgoto out;\n\n\t\t/* Decipher the longpoll URL, if any, and store it in ->lp_url */\n\t\tif (pool->hdr_path) {\n\t\t\tchar *copy_start, *hdr_path;\n\t\t\tbool need_slash = false;\n\n\t\t\thdr_path = pool->hdr_path;\n\t\t\tif (strstr(hdr_path, \"://\")) {\n\t\t\t\tpool->lp_url = hdr_path;\n\t\t\t\thdr_path = NULL;\n\t\t\t} else {\n\t\t\t\t/* absolute path, on current server */\n\t\t\t\tcopy_start = (*hdr_path == '/') ? (hdr_path + 1) : hdr_path;\n\t\t\t\tif (pool->rpc_url[strlen(pool->rpc_url) - 1] != '/')\n\t\t\t\t\tneed_slash = true;\n\n\t\t\t\tpool->lp_url = malloc(strlen(pool->rpc_url) + strlen(copy_start) + 2);\n\t\t\t\tif (!pool->lp_url) {\n\t\t\t\t\tapplog(LOG_ERR, \"Malloc failure in pool_active\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tsprintf(pool->lp_url, \"%s%s%s\", pool->rpc_url, need_slash ? \"/\" : \"\", copy_start);\n\t\t\t}\n\t\t} else\n\t\t\tpool->lp_url = NULL;\n\n\t\tif (!pool->lp_started) {\n\t\t\tpool->lp_started = true;\n\t\t\tif (unlikely(pthread_create(&pool->longpoll_thread, NULL, longpoll_thread, (void *)pool)))\n\t\t\t\tquit(1, \"Failed to create pool longpoll thread\");\n\t\t}\n\t} else {\n\t\t/* If we failed to parse a getwork, this could be a stratum\n\t\t * url without the prefix stratum+tcp:// so let's check it */\n\t\tif (initiate_stratum(pool)) {\n\t\t\tpool->has_stratum = true;\n\t\t\tgoto retry_stratum;\n\t\t}\n\t\tapplog(LOG_DEBUG, \"FAILED to retrieve work from pool %u %s\",\n\t\t       pool->pool_no, pool->rpc_url);\n\t\tif (!pinging)\n\t\t\tapplog(LOG_WARNING, \"Pool %u slow/down or URL or credentials invalid\", pool->pool_no);\n\t}\nout:\n\tcurl_easy_cleanup(curl);\n\treturn ret;\n}\n\nstatic void pool_resus(struct pool *pool)\n{\n\tif (pool_strategy == POOL_FAILOVER && pool->prio < cp_prio()) {\n\t\tapplog(LOG_WARNING, \"Pool %d %s alive\", pool->pool_no, pool->rpc_url);\n\t\tswitch_pools(NULL);\n\t} else\n\t\tapplog(LOG_INFO, \"Pool %d %s alive\", pool->pool_no, pool->rpc_url);\n}\n\nstatic struct work *hash_pop(void)\n{\n\tstruct work *work = NULL, *tmp;\n\tint hc;\n\n\tmutex_lock(stgd_lock);\n\twhile (!getq->frozen && !HASH_COUNT(staged_work))\n\t\tpthread_cond_wait(&getq->cond, stgd_lock);\n\n\thc = HASH_COUNT(staged_work);\n\t/* Find clone work if possible, to allow masters to be reused */\n\tif (hc > staged_rollable) {\n\t\tHASH_ITER(hh, staged_work, work, tmp) {\n\t\t\tif (!work_rollable(work))\n\t\t\t\tbreak;\n\t\t}\n\t} else\n\t\twork = staged_work;\n\tHASH_DEL(staged_work, work);\n\tif (work_rollable(work))\n\t\tstaged_rollable--;\n\n\t/* Signal the getwork scheduler to look for more work */\n\tpthread_cond_signal(&gws_cond);\n\n\t/* Signal hash_pop again in case there are mutliple hash_pop waiters */\n\tpthread_cond_signal(&getq->cond);\n\tmutex_unlock(stgd_lock);\n\n\treturn work;\n}\n\n/* Clones work by rolling it if possible, and returning a clone instead of the\n * original work item which gets staged again to possibly be rolled again in\n * the future */\nstatic struct work *clone_work(struct work *work)\n{\n\tint mrs = mining_threads + opt_queue - total_staged();\n\tstruct work *work_clone;\n\tbool cloned;\n\n\tif (mrs < 1)\n\t\treturn work;\n\n\tcloned = false;\n\twork_clone = make_clone(work);\n\twhile (mrs-- > 0 && can_roll(work) && should_roll(work)) {\n\t\tapplog(LOG_DEBUG, \"Pushing rolled converted work to stage thread\");\n\t\tstage_work(work_clone);\n\t\troll_work(work);\n\t\twork_clone = make_clone(work);\n\t\t/* Roll it again to prevent duplicates should this be used\n\t\t * directly later on */\n\t\troll_work(work);\n\t\tcloned = true;\n\t}\n\n\tif (cloned) {\n\t\tstage_work(work);\n\t\treturn work_clone;\n\t}\n\n\tfree_work(work_clone);\n\n\treturn work;\n}\n\nstatic void gen_hash(unsigned char *data, unsigned char *hash, int len)\n{\n\tunsigned char hash1[32];\n\n\tsha2(data, len, hash1);\n\tsha2(hash1, 32, hash);\n}\n\n/* Diff 1 is a 256 bit unsigned integer of\n * 0x00000000ffff0000000000000000000000000000000000000000000000000000\n * so we use a big endian 64 bit unsigned integer centred on the 5th byte to\n * cover a huge range of difficulty targets, though not all 256 bits' worth */\nvoid set_target(unsigned char *dest_target, double diff)\n{\n\tunsigned char target[32];\n\tuint64_t *data64, h64;\n\tdouble d64;\n\n\td64 = diffone;\n\td64 /= diff;\n\th64 = d64;\n\n\tmemset(target, 0, 32);\n\tif (h64) {\n\t\tunsigned char rtarget[32];\n\n\t\tmemset(rtarget, 0, 32);\n\t\tif (opt_scrypt)\n\t\t\tdata64 = (uint64_t *)(rtarget + 2);\n\t\telse\n\t\t\tdata64 = (uint64_t *)(rtarget + 4);\n\t\t*data64 = htobe64(h64);\n\t\tswab256(target, rtarget);\n\t} else {\n\t\t/* Support for the classic all FFs just-below-1 diff */\n\t\tif (opt_scrypt)\n\t\t\tmemset(target, 0xff, 30);\n\t\telse\n\t\t\tmemset(target, 0xff, 28);\n\t}\n\n\tif (opt_debug) {\n\t\tchar *htarget = bin2hex(target, 32);\n\n\t\tapplog(LOG_DEBUG, \"Generated target %s\", htarget);\n\t\tfree(htarget);\n\t}\n\tmemcpy(dest_target, target, 32);\n}\n\n/* Generates stratum based work based on the most recent notify information\n * from the pool. This will keep generating work while a pool is down so we use\n * other means to detect when the pool has died in stratum_thread */\nstatic void gen_stratum_work(struct pool *pool, struct work *work)\n{\n\tunsigned char *coinbase, merkle_root[32], merkle_sha[64];\n\tchar *header, *merkle_hash;\n\tuint32_t *data32, *swap32;\n\tsize_t alloc_len;\n\tint i;\n\n\t/* Use intermediate lock to update the one pool variable */\n\tcg_ilock(&pool->data_lock);\n\n\t/* Generate coinbase */\n\twork->nonce2 = bin2hex((const unsigned char *)&pool->nonce2, pool->n2size);\n\tpool->nonce2++;\n\n\t/* Downgrade to a read lock to read off the pool variables */\n\tcg_dlock(&pool->data_lock);\n\talloc_len = pool->swork.cb_len;\n\talign_len(&alloc_len);\n\tcoinbase = calloc(alloc_len, 1);\n\tif (unlikely(!coinbase))\n\t\tquit(1, \"Failed to calloc coinbase in gen_stratum_work\");\n\thex2bin(coinbase, pool->swork.coinbase1, pool->swork.cb1_len);\n\thex2bin(coinbase + pool->swork.cb1_len, pool->nonce1, pool->n1_len);\n\thex2bin(coinbase + pool->swork.cb1_len + pool->n1_len, work->nonce2, pool->n2size);\n\thex2bin(coinbase + pool->swork.cb1_len + pool->n1_len + pool->n2size, pool->swork.coinbase2, pool->swork.cb2_len);\n\n\t/* Generate merkle root */\n\tgen_hash(coinbase, merkle_root, pool->swork.cb_len);\n\tfree(coinbase);\n\tmemcpy(merkle_sha, merkle_root, 32);\n\tfor (i = 0; i < pool->swork.merkles; i++) {\n\t\tunsigned char merkle_bin[32];\n\n\t\thex2bin(merkle_bin, pool->swork.merkle[i], 32);\n\t\tmemcpy(merkle_sha + 32, merkle_bin, 32);\n\t\tgen_hash(merkle_sha, merkle_root, 64);\n\t\tmemcpy(merkle_sha, merkle_root, 32);\n\t}\n\tdata32 = (uint32_t *)merkle_sha;\n\tswap32 = (uint32_t *)merkle_root;\n\tflip32(swap32, data32);\n\tmerkle_hash = bin2hex((const unsigned char *)merkle_root, 32);\n\n\theader = calloc(pool->swork.header_len, 1);\n\tif (unlikely(!header))\n\t\tquit(1, \"Failed to calloc header in gen_stratum_work\");\n\tsprintf(header, \"%s%s%s%s%s%s%s\",\n\t\tpool->swork.bbversion,\n\t\tpool->swork.prev_hash,\n\t\tmerkle_hash,\n\t\tpool->swork.ntime,\n\t\tpool->swork.nbit,\n\t\t\"00000000\", /* nonce */\n\t\tworkpadding);\n\n\t/* Store the stratum work diff to check it still matches the pool's\n\t * stratum diff when submitting shares */\n\twork->sdiff = pool->swork.diff;\n\n\t/* Copy parameters required for share submission */\n\twork->job_id = strdup(pool->swork.job_id);\n\twork->nonce1 = strdup(pool->nonce1);\n\twork->ntime = strdup(pool->swork.ntime);\n\tcg_runlock(&pool->data_lock);\n\n\tapplog(LOG_DEBUG, \"Generated stratum merkle %s\", merkle_hash);\n\tapplog(LOG_DEBUG, \"Generated stratum header %s\", header);\n\tapplog(LOG_DEBUG, \"Work job_id %s nonce2 %s ntime %s\", work->job_id, work->nonce2, work->ntime);\n\n\tfree(merkle_hash);\n\n\t/* Convert hex data to binary data for work */\n\tif (unlikely(!hex2bin(work->data, header, 128)))\n\t\tquit(1, \"Failed to convert header to data in gen_stratum_work\");\n\tfree(header);\n\tcalc_midstate(work);\n\n\tset_target(work->target, work->sdiff);\n\n\tlocal_work++;\n\twork->pool = pool;\n\twork->stratum = true;\n\twork->blk.nonce = 0;\n\twork->id = total_work++;\n\twork->longpoll = false;\n\twork->getwork_mode = GETWORK_MODE_STRATUM;\n\twork->work_block = work_block;\n\tcalc_diff(work, work->sdiff);\n\n\tcgtime(&work->tv_staged);\n}\n\nstatic struct work *get_work(struct thr_info *thr, const int thr_id)\n{\n\tstruct work *work = NULL;\n\n\t/* Tell the watchdog thread this thread is waiting on getwork and\n\t * should not be restarted */\n\tthread_reportout(thr);\n\n\tapplog(LOG_DEBUG, \"Popping work from get queue to get work\");\n\twhile (!work) {\n\t\twork = hash_pop();\n\t\tif (stale_work(work, false)) {\n\t\t\tdiscard_work(work);\n\t\t\twork = NULL;\n\t\t\twake_gws();\n\t\t}\n\t}\n\tapplog(LOG_DEBUG, \"Got work from get queue to get work for thread %d\", thr_id);\n\n\twork->thr_id = thr_id;\n\tthread_reportin(thr);\n\twork->mined = true;\n\treturn work;\n}\n\nvoid submit_work_async(struct work *work_in, struct timeval *tv_work_found)\n{\n\tstruct work *work = copy_work(work_in);\n\tpthread_t submit_thread;\n\n\tif (tv_work_found)\n\t\tcopy_time(&work->tv_work_found, tv_work_found);\n\tapplog(LOG_DEBUG, \"Pushing submit work to work thread\");\n\tif (unlikely(pthread_create(&submit_thread, NULL, submit_work_thread, (void *)work)))\n\t\tquit(1, \"Failed to create submit_work_thread\");\n}\n\nvoid inc_hw_errors(struct thr_info *thr)\n{\n\tmutex_lock(&stats_lock);\n\thw_errors++;\n\tthr->cgpu->hw_errors++;\n\tmutex_unlock(&stats_lock);\n\n\tthr->cgpu->drv->hw_error(thr);\n}\n\nvoid submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)\n{\n\tuint32_t *work_nonce = (uint32_t *)(work->data + 64 + 12);\n\tstruct timeval tv_work_found;\n\tunsigned char hash2[32];\n\tuint32_t *hash2_32 = (uint32_t *)hash2;\n\tuint32_t diff1targ;\n\n\tcgtime(&tv_work_found);\n\t*work_nonce = htole32(nonce);\n\n\tmutex_lock(&stats_lock);\n\ttotal_diff1 += work->device_diff;\n\tthr->cgpu->diff1 += work->device_diff;\n\twork->pool->diff1 += work->device_diff;\n\tmutex_unlock(&stats_lock);\n\n\t/* Do one last check before attempting to submit the work */\n\trebuild_hash(work);\n\tflip32(hash2_32, work->hash);\n\n\tdiff1targ = opt_scrypt ? 0x0000ffffUL : 0;\n\tif (be32toh(hash2_32[7]) > diff1targ) {\n\t\tapplog(LOG_WARNING, \"%s%d: invalid nonce - HW error\",\n\t\t\t\tthr->cgpu->drv->name, thr->cgpu->device_id);\n\n\t\tinc_hw_errors(thr);\n\t\treturn;\n\t}\n\n\tmutex_lock(&stats_lock);\n\tthr->cgpu->last_device_valid_work = time(NULL);\n\tmutex_unlock(&stats_lock);\n\n\tif (!fulltest(hash2, work->target)) {\n\t\tapplog(LOG_INFO, \"Share below target\");\n\t\treturn;\n\t}\n\n\tsubmit_work_async(work, &tv_work_found);\n}\n\nstatic inline bool abandon_work(struct work *work, struct timeval *wdiff, uint64_t hashes)\n{\n\tif (wdiff->tv_sec > opt_scantime ||\n\t    work->blk.nonce >= MAXTHREADS - hashes ||\n\t    hashes >= 0xfffffffe ||\n\t    stale_work(work, false))\n\t\treturn true;\n\treturn false;\n}\n\nstatic void mt_disable(struct thr_info *mythr, const int thr_id,\n\t\t       struct device_drv *drv)\n{\n\tapplog(LOG_WARNING, \"Thread %d being disabled\", thr_id);\n\tmythr->rolling = mythr->cgpu->rolling = 0;\n\tapplog(LOG_DEBUG, \"Popping wakeup ping in miner thread\");\n\tthread_reportout(mythr);\n\tdo {\n\t\ttq_pop(mythr->q, NULL); /* Ignore ping that's popped */\n\t} while (mythr->pause);\n\tthread_reportin(mythr);\n\tapplog(LOG_WARNING, \"Thread %d being re-enabled\", thr_id);\n\tdrv->thread_enable(mythr);\n}\n\n/* The main hashing loop for devices that are slow enough to work on one work\n * item at a time, without a queue, aborting work before the entire nonce\n * range has been hashed if needed. */\nstatic void hash_sole_work(struct thr_info *mythr)\n{\n\tconst int thr_id = mythr->id;\n\tstruct cgpu_info *cgpu = mythr->cgpu;\n\tstruct device_drv *drv = cgpu->drv;\n\tstruct timeval getwork_start, tv_start, *tv_end, tv_workstart, tv_lastupdate;\n\tstruct cgminer_stats *dev_stats = &(cgpu->cgminer_stats);\n\tstruct cgminer_stats *pool_stats;\n\t/* Try to cycle approximately 5 times before each log update */\n\tconst long cycle = opt_log_interval / 5 ? : 1;\n\tconst bool primary = (!mythr->device_thread) || mythr->primary_thread;\n\tstruct timeval diff, sdiff, wdiff = {0, 0};\n\tuint32_t max_nonce = drv->can_limit_work(mythr);\n\tint64_t hashes_done = 0;\n\n\ttv_end = &getwork_start;\n\tcgtime(&getwork_start);\n\tsdiff.tv_sec = sdiff.tv_usec = 0;\n\tcgtime(&tv_lastupdate);\n\n\twhile (42) {\n\t\tstruct work *work = get_work(mythr, thr_id);\n\t\tint64_t hashes;\n\n\t\tmythr->work_restart = false;\n\t\tcgpu->new_work = true;\n\n\t\tcgtime(&tv_workstart);\n\t\twork->blk.nonce = 0;\n\t\tcgpu->max_hashes = 0;\n\t\tif (!drv->prepare_work(mythr, work)) {\n\t\t\tapplog(LOG_ERR, \"work prepare failed, exiting \"\n\t\t\t\t\"mining thread %d\", thr_id);\n\t\t\tbreak;\n\t\t}\n\t\twork->device_diff = MIN(drv->working_diff, work->work_difficulty);\n#ifdef USE_SCRYPT\n\t\t/* Dynamically adjust the working diff even if the target\n\t\t * diff is very high to ensure we can still validate scrypt is\n\t\t * returning shares. */\n\t\tif (opt_scrypt) {\n\t\t\tdouble wu;\n\n\t\t\twu = total_diff1 / total_secs * 60;\n\t\t\tif (wu > 30 && drv->working_diff < drv->max_diff &&\n\t\t\t    drv->working_diff < work->work_difficulty) {\n\t\t\t\tdrv->working_diff++;\n\t\t\t\tapplog(LOG_DEBUG, \"Driver %s working diff changed to %.0f\",\n\t\t\t\t\tdrv->dname, drv->working_diff);\n\t\t\t\twork->device_diff = MIN(drv->working_diff, work->work_difficulty);\n\t\t\t} else if (drv->working_diff > work->work_difficulty)\n\t\t\t\tdrv->working_diff = work->work_difficulty;\n\t\t\tset_target(work->device_target, work->device_diff);\n\t\t}\n#endif\n\n\t\tdo {\n\t\t\tcgtime(&tv_start);\n\n\t\t\tsubtime(&tv_start, &getwork_start);\n\n\t\t\taddtime(&getwork_start, &dev_stats->getwork_wait);\n\t\t\tif (time_more(&getwork_start, &dev_stats->getwork_wait_max))\n\t\t\t\tcopy_time(&dev_stats->getwork_wait_max, &getwork_start);\n\t\t\tif (time_less(&getwork_start, &dev_stats->getwork_wait_min))\n\t\t\t\tcopy_time(&dev_stats->getwork_wait_min, &getwork_start);\n\t\t\tdev_stats->getwork_calls++;\n\n\t\t\tpool_stats = &(work->pool->cgminer_stats);\n\n\t\t\taddtime(&getwork_start, &pool_stats->getwork_wait);\n\t\t\tif (time_more(&getwork_start, &pool_stats->getwork_wait_max))\n\t\t\t\tcopy_time(&pool_stats->getwork_wait_max, &getwork_start);\n\t\t\tif (time_less(&getwork_start, &pool_stats->getwork_wait_min))\n\t\t\t\tcopy_time(&pool_stats->getwork_wait_min, &getwork_start);\n\t\t\tpool_stats->getwork_calls++;\n\n\t\t\tcgtime(&(work->tv_work_start));\n\n\t\t\tthread_reportin(mythr);\n\t\t\thashes = drv->scanhash(mythr, work, work->blk.nonce + max_nonce);\n\t\t\tthread_reportin(mythr);\n\n\t\t\t/* tv_end is == &getwork_start */\n\t\t\tcgtime(&getwork_start);\n\n\t\t\tif (unlikely(hashes == -1)) {\n\t\t\t\tapplog(LOG_ERR, \"%s %d failure, disabling!\", drv->name, cgpu->device_id);\n\t\t\t\tcgpu->deven = DEV_DISABLED;\n\t\t\t\tdev_error(cgpu, REASON_THREAD_ZERO_HASH);\n\t\t\t\tmt_disable(mythr, thr_id, drv);\n\t\t\t}\n\n\t\t\thashes_done += hashes;\n\t\t\tif (hashes > cgpu->max_hashes)\n\t\t\t\tcgpu->max_hashes = hashes;\n\n\t\t\ttimersub(tv_end, &tv_start, &diff);\n\t\t\tsdiff.tv_sec += diff.tv_sec;\n\t\t\tsdiff.tv_usec += diff.tv_usec;\n\t\t\tif (sdiff.tv_usec > 1000000) {\n\t\t\t\t++sdiff.tv_sec;\n\t\t\t\tsdiff.tv_usec -= 1000000;\n\t\t\t}\n\n\t\t\ttimersub(tv_end, &tv_workstart, &wdiff);\n\n\t\t\tif (unlikely((long)sdiff.tv_sec < cycle)) {\n\t\t\t\tint mult;\n\n\t\t\t\tif (likely(max_nonce == 0xffffffff))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tmult = 1000000 / ((sdiff.tv_usec + 0x400) / 0x400) + 0x10;\n\t\t\t\tmult *= cycle;\n\t\t\t\tif (max_nonce > (0xffffffff * 0x400) / mult)\n\t\t\t\t\tmax_nonce = 0xffffffff;\n\t\t\t\telse\n\t\t\t\t\tmax_nonce = (max_nonce * mult) / 0x400;\n\t\t\t} else if (unlikely(sdiff.tv_sec > cycle))\n\t\t\t\tmax_nonce = max_nonce * cycle / sdiff.tv_sec;\n\t\t\telse if (unlikely(sdiff.tv_usec > 100000))\n\t\t\t\tmax_nonce = max_nonce * 0x400 / (((cycle * 1000000) + sdiff.tv_usec) / (cycle * 1000000 / 0x400));\n\n\t\t\ttimersub(tv_end, &tv_lastupdate, &diff);\n\t\t\t/* Update the hashmeter at most 5 times per second */\n\t\t\tif (diff.tv_sec > 0 || diff.tv_usec > 200) {\n\t\t\t\thashmeter(thr_id, &diff, hashes_done);\n\t\t\t\thashes_done = 0;\n\t\t\t\tcopy_time(&tv_lastupdate, tv_end);\n\t\t\t}\n\n\t\t\tif (unlikely(mythr->work_restart)) {\n\t\t\t\t/* Apart from device_thread 0, we stagger the\n\t\t\t\t * starting of every next thread to try and get\n\t\t\t\t * all devices busy before worrying about\n\t\t\t\t * getting work for their extra threads */\n\t\t\t\tif (!primary) {\n\t\t\t\t\tstruct timespec rgtp;\n\n\t\t\t\t\trgtp.tv_sec = 0;\n\t\t\t\t\trgtp.tv_nsec = 250 * mythr->device_thread * 1000000;\n\t\t\t\t\tnanosleep(&rgtp, NULL);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (unlikely(mythr->pause || cgpu->deven != DEV_ENABLED))\n\t\t\t\tmt_disable(mythr, thr_id, drv);\n\n\t\t\tsdiff.tv_sec = sdiff.tv_usec = 0;\n\t\t} while (!abandon_work(work, &wdiff, cgpu->max_hashes));\n\t\tfree_work(work);\n\t}\n}\n\n/* Create a hashtable of work items for devices with a queue. The device\n * driver must have a custom queue_full function or it will default to true\n * and put only one work item in the queue. Work items should not be removed\n * from this hashtable until they are no longer in use anywhere. Once a work\n * item is physically queued on the device itself, the work->queued flag\n * should be set under cgpu->qlock write lock to prevent it being dereferenced\n * while still in use. */\nstatic void fill_queue(struct thr_info *mythr, struct cgpu_info *cgpu, struct device_drv *drv, const int thr_id)\n{\n\tthread_reportout(mythr);\n\tdo {\n\t\tbool need_work;\n\n\t\trd_lock(&cgpu->qlock);\n\t\tneed_work = (HASH_COUNT(cgpu->queued_work) == cgpu->queued_count);\n\t\trd_unlock(&cgpu->qlock);\n\n\t\tif (need_work) {\n\t\t\tstruct work *work = get_work(mythr, thr_id);\n\n\t\t\twork->device_diff = MIN(drv->max_diff, work->work_difficulty);\n\t\t\twr_lock(&cgpu->qlock);\n\t\t\tHASH_ADD_INT(cgpu->queued_work, id, work);\n\t\t\twr_unlock(&cgpu->qlock);\n\t\t}\n\t\t/* The queue_full function should be used by the driver to\n\t\t * actually place work items on the physical device if it\n\t\t * does have a queue. */\n\t} while (!drv->queue_full(cgpu));\n}\n\n/* This function is for retrieving one work item from the queued hashtable of\n * available work items that are not yet physically on a device (which is\n * flagged with the work->queued bool). Code using this function must be able\n * to handle NULL as a return which implies there is no work available. */\nstruct work *get_queued(struct cgpu_info *cgpu)\n{\n\tstruct work *work, *tmp, *ret = NULL;\n\n\twr_lock(&cgpu->qlock);\n\tHASH_ITER(hh, cgpu->queued_work, work, tmp) {\n\t\tif (!work->queued) {\n\t\t\twork->queued = true;\n\t\t\tcgpu->queued_count++;\n\t\t\tret = work;\n\t\t\tbreak;\n\t\t}\n\t}\n\twr_unlock(&cgpu->qlock);\n\n\treturn ret;\n}\n\n/* This function is for finding an already queued work item in the\n * given que hashtable. Code using this function must be able\n * to handle NULL as a return which implies there is no matching work.\n * The calling function must lock access to the que if it is required.\n * The common values for midstatelen, offset, datalen are 32, 64, 12 */\nstruct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen)\n{\n\tstruct work *work, *tmp, *ret = NULL;\n\n\tHASH_ITER(hh, que, work, tmp) {\n\t\tif (work->queued &&\n\t\t    memcmp(work->midstate, midstate, midstatelen) == 0 &&\n\t\t    memcmp(work->data + offset, data, datalen) == 0) {\n\t\t\tret = work;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn ret;\n}\n\n/* This function is for finding an already queued work item in the\n * device's queued_work hashtable. Code using this function must be able\n * to handle NULL as a return which implies there is no matching work.\n * The common values for midstatelen, offset, datalen are 32, 64, 12 */\nstruct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen)\n{\n\tstruct work *ret;\n\n\trd_lock(&cgpu->qlock);\n\tret = __find_work_bymidstate(cgpu->queued_work, midstate, midstatelen, data, offset, datalen);\n\trd_unlock(&cgpu->qlock);\n\n\treturn ret;\n}\n\n/* This function should be used by queued device drivers when they're sure\n * the work struct is no longer in use. */\nvoid work_completed(struct cgpu_info *cgpu, struct work *work)\n{\n\twr_lock(&cgpu->qlock);\n\tif (work->queued)\n\t\tcgpu->queued_count--;\n\tHASH_DEL(cgpu->queued_work, work);\n\twr_unlock(&cgpu->qlock);\n\n\tfree_work(work);\n}\n\nstatic void flush_queue(struct cgpu_info *cgpu)\n{\n\tstruct work *work, *tmp;\n\tint discarded = 0;\n\n\twr_lock(&cgpu->qlock);\n\tHASH_ITER(hh, cgpu->queued_work, work, tmp) {\n\t\t/* Can only discard the work items if they're not physically\n\t\t * queued on the device. */\n\t\tif (!work->queued) {\n\t\t\tHASH_DEL(cgpu->queued_work, work);\n\t\t\tdiscard_work(work);\n\t\t\tdiscarded++;\n\t\t}\n\t}\n\twr_unlock(&cgpu->qlock);\n\n\tif (discarded)\n\t\tapplog(LOG_DEBUG, \"Discarded %d queued work items\", discarded);\n}\n\n/* This version of hash work is for devices that are fast enough to always\n * perform a full nonce range and need a queue to maintain the device busy.\n * Work creation and destruction is not done from within this function\n * directly. */\nvoid hash_queued_work(struct thr_info *mythr)\n{\n\tstruct timeval tv_start = {0, 0}, tv_end;\n\tstruct cgpu_info *cgpu = mythr->cgpu;\n\tstruct device_drv *drv = cgpu->drv;\n\tconst int thr_id = mythr->id;\n\tint64_t hashes_done = 0;\n\n\twhile (42) {\n\t\tstruct timeval diff;\n\t\tint64_t hashes;\n\n\t\tmythr->work_restart = false;\n\n\t\tfill_queue(mythr, cgpu, drv, thr_id);\n\n\t\tthread_reportin(mythr);\n\t\thashes = drv->scanwork(mythr);\n\t\tif (unlikely(hashes == -1 )) {\n\t\t\tapplog(LOG_ERR, \"%s %d failure, disabling!\", drv->name, cgpu->device_id);\n\t\t\tcgpu->deven = DEV_DISABLED;\n\t\t\tdev_error(cgpu, REASON_THREAD_ZERO_HASH);\n\t\t\tmt_disable(mythr, thr_id, drv);\n\t\t}\n\n\t\thashes_done += hashes;\n\t\tcgtime(&tv_end);\n\t\ttimersub(&tv_end, &tv_start, &diff);\n\t\t/* Update the hashmeter at most 5 times per second */\n\t\tif (diff.tv_sec > 0 || diff.tv_usec > 200) {\n\t\t\thashmeter(thr_id, &diff, hashes_done);\n\t\t\thashes_done = 0;\n\t\t\tcopy_time(&tv_start, &tv_end);\n\t\t}\n\n\t\tif (unlikely(mythr->pause || cgpu->deven != DEV_ENABLED))\n\t\t\tmt_disable(mythr, thr_id, drv);\n\n\t\tif (unlikely(mythr->work_restart)) {\n\t\t\tflush_queue(cgpu);\n\t\t\tdrv->flush_work(cgpu);\n\t\t}\n\t}\n}\n\nvoid *miner_thread(void *userdata)\n{\n\tstruct thr_info *mythr = userdata;\n\tconst int thr_id = mythr->id;\n\tstruct cgpu_info *cgpu = mythr->cgpu;\n\tstruct device_drv *drv = cgpu->drv;\n\tchar threadname[24];\n\n\tpthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);\n\n        snprintf(threadname, 24, \"miner/%d\", thr_id);\n\tRenameThread(threadname);\n\n\tif (!drv->thread_init(mythr)) {\n\t\tdev_error(cgpu, REASON_THREAD_FAIL_INIT);\n\t\tgoto out;\n\t}\n\n\tthread_reportout(mythr);\n\tapplog(LOG_DEBUG, \"Popping ping in miner thread\");\n\ttq_pop(mythr->q, NULL); /* Wait for a ping to start */\n\n\tdrv->hash_work(mythr);\nout:\n\tdrv->thread_shutdown(mythr);\n\n\tthread_reportin(mythr);\n\tapplog(LOG_ERR, \"Thread %d failure, exiting\", thr_id);\n\ttq_freeze(mythr->q);\n\n\treturn NULL;\n}\n\nenum {\n\tSTAT_SLEEP_INTERVAL\t\t= 1,\n\tSTAT_CTR_INTERVAL\t\t= 10000000,\n\tFAILURE_INTERVAL\t\t= 30,\n};\n\n/* Stage another work item from the work returned in a longpoll */\nstatic void convert_to_work(json_t *val, int rolltime, struct pool *pool, struct timeval *tv_lp, struct timeval *tv_lp_reply)\n{\n\tstruct work *work;\n\tbool rc;\n\n\twork = make_work();\n\n\trc = work_decode(pool, work, val);\n\tif (unlikely(!rc)) {\n\t\tapplog(LOG_ERR, \"Could not convert longpoll data to work\");\n\t\tfree_work(work);\n\t\treturn;\n\t}\n\ttotal_getworks++;\n\tpool->getwork_requested++;\n\twork->pool = pool;\n\twork->rolltime = rolltime;\n\tcopy_time(&work->tv_getwork, tv_lp);\n\tcopy_time(&work->tv_getwork_reply, tv_lp_reply);\n\tcalc_diff(work, 0);\n\n\tif (pool->enabled == POOL_REJECTING)\n\t\twork->mandatory = true;\n\n\tif (pool->has_gbt)\n\t\tgen_gbt_work(pool, work);\n\twork->longpoll = true;\n\twork->getwork_mode = GETWORK_MODE_LP;\n\n\t/* We'll be checking this work item twice, but we already know it's\n\t * from a new block so explicitly force the new block detection now\n\t * rather than waiting for it to hit the stage thread. This also\n\t * allows testwork to know whether LP discovered the block or not. */\n\ttest_work_current(work);\n\n\t/* Don't use backup LPs as work if we have failover-only enabled. Use\n\t * the longpoll work from a pool that has been rejecting shares as a\n\t * way to detect when the pool has recovered.\n\t */\n\tif (pool != current_pool() && opt_fail_only && pool->enabled != POOL_REJECTING) {\n\t\tfree_work(work);\n\t\treturn;\n\t}\n\n\twork = clone_work(work);\n\n\tapplog(LOG_DEBUG, \"Pushing converted work to stage thread\");\n\n\tstage_work(work);\n\tapplog(LOG_DEBUG, \"Converted longpoll data to work\");\n}\n\n/* If we want longpoll, enable it for the chosen default pool, or, if\n * the pool does not support longpoll, find the first one that does\n * and use its longpoll support */\nstatic struct pool *select_longpoll_pool(struct pool *cp)\n{\n\tint i;\n\n\tif (cp->hdr_path || cp->has_gbt)\n\t\treturn cp;\n\tfor (i = 0; i < total_pools; i++) {\n\t\tstruct pool *pool = pools[i];\n\n\t\tif (pool->has_stratum || pool->hdr_path)\n\t\t\treturn pool;\n\t}\n\treturn NULL;\n}\n\n/* This will make the longpoll thread wait till it's the current pool, or it\n * has been flagged as rejecting, before attempting to open any connections.\n */\nstatic void wait_lpcurrent(struct pool *pool)\n{\n\tif (cnx_needed(pool))\n\t\treturn;\n\n\twhile (pool != current_pool() && pool_strategy != POOL_LOADBALANCE && pool_strategy != POOL_BALANCE) {\n\t\tmutex_lock(&lp_lock);\n\t\tpthread_cond_wait(&lp_cond, &lp_lock);\n\t\tmutex_unlock(&lp_lock);\n\t}\n}\n\nstatic void *longpoll_thread(void *userdata)\n{\n\tstruct pool *cp = (struct pool *)userdata;\n\t/* This *pool is the source of the actual longpoll, not the pool we've\n\t * tied it to */\n\tstruct timeval start, reply, end;\n\tstruct pool *pool = NULL;\n\tchar threadname[16];\n\tCURL *curl = NULL;\n\tint failures = 0;\n\tchar lpreq[1024];\n\tchar *lp_url;\n\tint rolltime;\n\n\tsnprintf(threadname, 16, \"longpoll/%d\", cp->pool_no);\n\tRenameThread(threadname);\n\n\tcurl = curl_easy_init();\n\tif (unlikely(!curl)) {\n\t\tapplog(LOG_ERR, \"CURL initialisation failed\");\n\t\treturn NULL;\n\t}\n\nretry_pool:\n\tpool = select_longpoll_pool(cp);\n\tif (!pool) {\n\t\tapplog(LOG_WARNING, \"No suitable long-poll found for %s\", cp->rpc_url);\n\t\twhile (!pool) {\n\t\t\tnmsleep(60000);\n\t\t\tpool = select_longpoll_pool(cp);\n\t\t}\n\t}\n\n\tif (pool->has_stratum) {\n\t\tapplog(LOG_WARNING, \"Block change for %s detection via %s stratum\",\n\t\t       cp->rpc_url, pool->rpc_url);\n\t\tgoto out;\n\t}\n\n\t/* Any longpoll from any pool is enough for this to be true */\n\thave_longpoll = true;\n\n\twait_lpcurrent(cp);\n\n\tif (pool->has_gbt) {\n\t\tlp_url = pool->rpc_url;\n\t\tapplog(LOG_WARNING, \"GBT longpoll ID activated for %s\", lp_url);\n\t} else {\n\t\tstrcpy(lpreq, getwork_req);\n\n\t\tlp_url = pool->lp_url;\n\t\tif (cp == pool)\n\t\t\tapplog(LOG_WARNING, \"Long-polling activated for %s\", lp_url);\n\t\telse\n\t\t\tapplog(LOG_WARNING, \"Long-polling activated for %s via %s\", cp->rpc_url, lp_url);\n\t}\n\n\twhile (42) {\n\t\tjson_t *val, *soval;\n\n\t\twait_lpcurrent(cp);\n\n\t\tcgtime(&start);\n\n\t\t/* Update the longpollid every time, but do it under lock to\n\t\t * avoid races */\n\t\tif (pool->has_gbt) {\n\t\t\tcg_rlock(&pool->gbt_lock);\n\t\t\tsprintf(lpreq, \"{\\\"id\\\": 0, \\\"method\\\": \\\"getblocktemplate\\\", \\\"params\\\": \"\n\t\t\t\t\"[{\\\"capabilities\\\": [\\\"coinbasetxn\\\", \\\"workid\\\", \\\"coinbase/append\\\"], \"\n\t\t\t\t\"\\\"longpollid\\\": \\\"%s\\\"}]}\\n\", pool->longpollid);\n\t\t\tcg_runlock(&pool->gbt_lock);\n\t\t}\n\n\t\t/* Longpoll connections can be persistent for a very long time\n\t\t * and any number of issues could have come up in the meantime\n\t\t * so always establish a fresh connection instead of relying on\n\t\t * a persistent one. */\n\t\tcurl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1);\n\t\tval = json_rpc_call(curl, lp_url, pool->rpc_userpass,\n\t\t\t\t    lpreq, false, true, &rolltime, pool, false);\n\n\t\tcgtime(&reply);\n\n\t\tif (likely(val)) {\n\t\t\tsoval = json_object_get(json_object_get(val, \"result\"), \"submitold\");\n\t\t\tif (soval)\n\t\t\t\tpool->submit_old = json_is_true(soval);\n\t\t\telse\n\t\t\t\tpool->submit_old = false;\n\t\t\tconvert_to_work(val, rolltime, pool, &start, &reply);\n\t\t\tfailures = 0;\n\t\t\tjson_decref(val);\n\t\t} else {\n\t\t\t/* Some pools regularly drop the longpoll request so\n\t\t\t * only see this as longpoll failure if it happens\n\t\t\t * immediately and just restart it the rest of the\n\t\t\t * time. */\n\t\t\tcgtime(&end);\n\t\t\tif (end.tv_sec - start.tv_sec > 30)\n\t\t\t\tcontinue;\n\t\t\tif (failures == 1)\n\t\t\t\tapplog(LOG_WARNING, \"longpoll failed for %s, retrying every 30s\", lp_url);\n\t\t\tnmsleep(30000);\n\t\t}\n\n\t\tif (pool != cp) {\n\t\t\tpool = select_longpoll_pool(cp);\n\t\t\tif (pool->has_stratum) {\n\t\t\t\tapplog(LOG_WARNING, \"Block change for %s detection via %s stratum\",\n\t\t\t\t       cp->rpc_url, pool->rpc_url);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (unlikely(!pool))\n\t\t\t\tgoto retry_pool;\n\t\t}\n\n\t\tif (unlikely(pool->removed))\n\t\t\tbreak;\n\t}\n\nout:\n\tcurl_easy_cleanup(curl);\n\n\treturn NULL;\n}\n\nvoid reinit_device(struct cgpu_info *cgpu)\n{\n\tcgpu->drv->reinit_device(cgpu);\n}\n\nstatic struct timeval rotate_tv;\n\n/* We reap curls if they are unused for over a minute */\nstatic void reap_curl(struct pool *pool)\n{\n\tstruct curl_ent *ent, *iter;\n\tstruct timeval now;\n\tint reaped = 0;\n\n\tcgtime(&now);\n\n\tmutex_lock(&pool->pool_lock);\n\tlist_for_each_entry_safe(ent, iter, &pool->curlring, node) {\n\t\tif (pool->curls < 2)\n\t\t\tbreak;\n\t\tif (now.tv_sec - ent->tv.tv_sec > 300) {\n\t\t\treaped++;\n\t\t\tpool->curls--;\n\t\t\tlist_del(&ent->node);\n\t\t\tcurl_easy_cleanup(ent->curl);\n\t\t\tfree(ent);\n\t\t}\n\t}\n\tmutex_unlock(&pool->pool_lock);\n\n\tif (reaped)\n\t\tapplog(LOG_DEBUG, \"Reaped %d curl%s from pool %d\", reaped, reaped > 1 ? \"s\" : \"\", pool->pool_no);\n}\n\nstatic void *watchpool_thread(void __maybe_unused *userdata)\n{\n\tint intervals = 0;\n\n\tpthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);\n\n\tRenameThread(\"watchpool\");\n\n\twhile (42) {\n\t\tstruct timeval now;\n\t\tint i;\n\n\t\tif (++intervals > 20)\n\t\t\tintervals = 0;\n\t\tcgtime(&now);\n\n\t\tfor (i = 0; i < total_pools; i++) {\n\t\t\tstruct pool *pool = pools[i];\n\n\t\t\tif (!opt_benchmark)\n\t\t\t\treap_curl(pool);\n\n\t\t\t/* Get a rolling utility per pool over 10 mins */\n\t\t\tif (intervals > 19) {\n\t\t\t\tint shares = pool->diff1 - pool->last_shares;\n\n\t\t\t\tpool->last_shares = pool->diff1;\n\t\t\t\tpool->utility = (pool->utility + (double)shares * 0.63) / 1.63;\n\t\t\t\tpool->shares = pool->utility;\n\t\t\t}\n\n\t\t\tif (pool->enabled == POOL_DISABLED)\n\t\t\t\tcontinue;\n\n\t\t\t/* Don't start testing any pools if the test threads\n\t\t\t * from startup are still doing their first attempt. */\n\t\t\tif (unlikely(pool->testing)) {\n\t\t\t\tpthread_join(pool->test_thread, NULL);\n\t\t\t\tpool->testing = false;\n\t\t\t}\n\n\t\t\t/* Test pool is idle once every minute */\n\t\t\tif (pool->idle && now.tv_sec - pool->tv_idle.tv_sec > 30) {\n\t\t\t\tcgtime(&pool->tv_idle);\n\t\t\t\tif (pool_active(pool, true) && pool_tclear(pool, &pool->idle))\n\t\t\t\t\tpool_resus(pool);\n\t\t\t}\n\t\t}\n\n\t\tif (pool_strategy == POOL_ROTATE && now.tv_sec - rotate_tv.tv_sec > 60 * opt_rotate_period) {\n\t\t\tcgtime(&rotate_tv);\n\t\t\tswitch_pools(NULL);\n\t\t}\n\n\t\tnmsleep(30000);\n\t\t\t\n\t}\n\treturn NULL;\n}\n\n/* Makes sure the hashmeter keeps going even if mining threads stall, updates\n * the screen at regular intervals, and restarts threads if they appear to have\n * died. */\n#define WATCHDOG_INTERVAL\t\t2\n//#define WATCHDOG_SICK_TIME\t\t60\n#define WATCHDOG_SICK_TIME\t\t300\t\t// KRAMBLE hack (its still not working properly though)\n//#define WATCHDOG_DEAD_TIME\t\t600\n#define WATCHDOG_DEAD_TIME\t\t1800\t// KRAMBLE\n#define WATCHDOG_SICK_COUNT\t\t(WATCHDOG_SICK_TIME/WATCHDOG_INTERVAL)\n#define WATCHDOG_DEAD_COUNT\t\t(WATCHDOG_DEAD_TIME/WATCHDOG_INTERVAL)\n\nstatic void *watchdog_thread(void __maybe_unused *userdata)\n{\n\tconst unsigned int interval = WATCHDOG_INTERVAL;\n\tstruct timeval zero_tv;\n\n\tpthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);\n\n\tRenameThread(\"watchdog\");\n\n\tmemset(&zero_tv, 0, sizeof(struct timeval));\n\tcgtime(&rotate_tv);\n\n\twhile (1) {\n\t\tint i;\n\t\tstruct timeval now;\n\n\t\tsleep(interval);\n\n\t\tdiscard_stale();\n\n\t\thashmeter(-1, &zero_tv, 0);\n\n#ifdef HAVE_CURSES\n\t\tif (curses_active_locked()) {\n\t\t\tchange_logwinsize();\n\t\t\tcurses_print_status();\n\t\t\tfor (i = 0; i < mining_threads; i++)\n\t\t\t\tcurses_print_devstatus(i);\n\t\t\ttouchwin(statuswin);\n\t\t\twrefresh(statuswin);\n\t\t\ttouchwin(logwin);\n\t\t\twrefresh(logwin);\n\t\t\tunlock_curses();\n\t\t}\n#endif\n\n\t\tcgtime(&now);\n\n\t\tif (!sched_paused && !should_run()) {\n\t\t\tapplog(LOG_WARNING, \"Pausing execution as per stop time %02d:%02d scheduled\",\n\t\t\t       schedstop.tm.tm_hour, schedstop.tm.tm_min);\n\t\t\tif (!schedstart.enable) {\n\t\t\t\tquit(0, \"Terminating execution as planned\");\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tapplog(LOG_WARNING, \"Will restart execution as scheduled at %02d:%02d\",\n\t\t\t       schedstart.tm.tm_hour, schedstart.tm.tm_min);\n\t\t\tsched_paused = true;\n\n\t\t\trd_lock(&mining_thr_lock);\n\t\t\tfor (i = 0; i < mining_threads; i++)\n\t\t\t\tmining_thr[i]->pause = true;\n\t\t\trd_unlock(&mining_thr_lock);\n\t\t} else if (sched_paused && should_run()) {\n\t\t\tapplog(LOG_WARNING, \"Restarting execution as per start time %02d:%02d scheduled\",\n\t\t\t\tschedstart.tm.tm_hour, schedstart.tm.tm_min);\n\t\t\tif (schedstop.enable)\n\t\t\t\tapplog(LOG_WARNING, \"Will pause execution as scheduled at %02d:%02d\",\n\t\t\t\t\tschedstop.tm.tm_hour, schedstop.tm.tm_min);\n\t\t\tsched_paused = false;\n\n\t\t\tfor (i = 0; i < mining_threads; i++) {\n\t\t\t\tstruct thr_info *thr;\n\n\t\t\t\tthr = get_thread(i);\n\n\t\t\t\t/* Don't touch disabled devices */\n\t\t\t\tif (thr->cgpu->deven == DEV_DISABLED)\n\t\t\t\t\tcontinue;\n\t\t\t\tthr->pause = false;\n\t\t\t\ttq_push(thr->q, &ping);\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < total_devices; ++i) {\n\t\t\tstruct cgpu_info *cgpu = get_devices(i);\n\t\t\tstruct thr_info *thr = cgpu->thr[0];\n\t\t\tenum dev_enable *denable;\n\t\t\tchar dev_str[8];\n\t\t\tint gpu;\n\n\t\t\tcgpu->drv->get_stats(cgpu);\n\n\t\t\tgpu = cgpu->device_id;\n\t\t\tdenable = &cgpu->deven;\n\t\t\tsprintf(dev_str, \"%s%d\", cgpu->drv->name, gpu);\n\n#ifdef HAVE_ADL\n\t\t\tif (adl_active && cgpu->has_adl)\n\t\t\t\tgpu_autotune(gpu, denable);\n\t\t\tif (opt_debug && cgpu->has_adl) {\n\t\t\t\tint engineclock = 0, memclock = 0, activity = 0, fanspeed = 0, fanpercent = 0, powertune = 0;\n\t\t\t\tfloat temp = 0, vddc = 0;\n\n\t\t\t\tif (gpu_stats(gpu, &temp, &engineclock, &memclock, &vddc, &activity, &fanspeed, &fanpercent, &powertune))\n\t\t\t\t\tapplog(LOG_DEBUG, \"%.1f C  F: %d%%(%dRPM)  E: %dMHz  M: %dMhz  V: %.3fV  A: %d%%  P: %d%%\",\n\t\t\t\t\ttemp, fanpercent, fanspeed, engineclock, memclock, vddc, activity, powertune);\n\t\t\t}\n#endif\n\t\t\t\n\t\t\t/* Thread is waiting on getwork or disabled */\n\t\t\tif (thr->getwork || *denable == DEV_DISABLED)\n\t\t\t\tcontinue;\n\n\t\t\tif (cgpu->status != LIFE_WELL && (now.tv_sec - thr->last.tv_sec < WATCHDOG_SICK_TIME)) {\n\t\t\t\tif (cgpu->status != LIFE_INIT)\n\t\t\t\tapplog(LOG_ERR, \"%s: Recovered, declaring WELL!\", dev_str);\n\t\t\t\tcgpu->status = LIFE_WELL;\n\t\t\t\tcgpu->device_last_well = time(NULL);\n\t\t\t} else if (cgpu->status == LIFE_WELL && (now.tv_sec - thr->last.tv_sec > WATCHDOG_SICK_TIME)) {\n\t\t\t\tthr->rolling = cgpu->rolling = 0;\n\t\t\t\tcgpu->status = LIFE_SICK;\n\t\t\t\tapplog(LOG_ERR, \"%s: Idle for more than 60 seconds, declaring SICK!\", dev_str);\n\t\t\t\tcgtime(&thr->sick);\n\n\t\t\t\tdev_error(cgpu, REASON_DEV_SICK_IDLE_60);\n#ifdef HAVE_ADL\n\t\t\t\tif (adl_active && cgpu->has_adl && gpu_activity(gpu) > 50) {\n\t\t\t\t\tapplog(LOG_ERR, \"GPU still showing activity suggesting a hard hang.\");\n\t\t\t\t\tapplog(LOG_ERR, \"Will not attempt to auto-restart it.\");\n\t\t\t\t} else\n#endif\n\t\t\t\tif (opt_restart) {\n\t\t\t\t\tapplog(LOG_ERR, \"%s: Attempting to restart\", dev_str);\n\t\t\t\t\treinit_device(cgpu);\n\t\t\t\t}\n\t\t\t} else if (cgpu->status == LIFE_SICK && (now.tv_sec - thr->last.tv_sec > WATCHDOG_DEAD_TIME)) {\n\t\t\t\tcgpu->status = LIFE_DEAD;\n\t\t\t\tapplog(LOG_ERR, \"%s: Not responded for more than 10 minutes, declaring DEAD!\", dev_str);\n\t\t\t\tcgtime(&thr->sick);\n\n\t\t\t\tdev_error(cgpu, REASON_DEV_DEAD_IDLE_600);\n\t\t\t} else if (now.tv_sec - thr->sick.tv_sec > 60 &&\n\t\t\t\t   (cgpu->status == LIFE_SICK || cgpu->status == LIFE_DEAD)) {\n\t\t\t\t/* Attempt to restart a GPU that's sick or dead once every minute */\n\t\t\t\tcgtime(&thr->sick);\n#ifdef HAVE_ADL\n\t\t\t\tif (adl_active && cgpu->has_adl && gpu_activity(gpu) > 50) {\n\t\t\t\t\t/* Again do not attempt to restart a device that may have hard hung */\n\t\t\t\t} else\n#endif\n\t\t\t\tif (opt_restart)\n\t\t\t\t\treinit_device(cgpu);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\nstatic void log_print_status(struct cgpu_info *cgpu)\n{\n\tchar logline[255];\n\n\tget_statline(logline, cgpu);\n\tapplog(LOG_WARNING, \"%s\", logline);\n}\n\nvoid print_summary(void)\n{\n\tstruct timeval diff;\n\tint hours, mins, secs, i;\n\tdouble utility, displayed_hashes, work_util;\n\tbool mhash_base = true;\n\n\ttimersub(&total_tv_end, &total_tv_start, &diff);\n\thours = diff.tv_sec / 3600;\n\tmins = (diff.tv_sec % 3600) / 60;\n\tsecs = diff.tv_sec % 60;\n\n\tutility = total_accepted / total_secs * 60;\n\twork_util = total_diff1 / total_secs * 60;\n\n\tapplog(LOG_WARNING, \"\\nSummary of runtime statistics:\\n\");\n\tapplog(LOG_WARNING, \"Started at %s\", datestamp);\n\tif (total_pools == 1)\n\t\tapplog(LOG_WARNING, \"Pool: %s\", pools[0]->rpc_url);\n\tapplog(LOG_WARNING, \"Runtime: %d hrs : %d mins : %d secs\", hours, mins, secs);\n\tdisplayed_hashes = total_mhashes_done / total_secs;\n\tif (displayed_hashes < 1) {\n\t\tdisplayed_hashes *= 1000;\n\t\tmhash_base = false;\n\t}\n\n\tapplog(LOG_WARNING, \"Average hashrate: %.1f %shash/s\", displayed_hashes, mhash_base? \"Mega\" : \"Kilo\");\n\tapplog(LOG_WARNING, \"Solved blocks: %d\", found_blocks);\n\tapplog(LOG_WARNING, \"Best share difficulty: %s\", best_share);\n\tapplog(LOG_WARNING, \"Share submissions: %d\", total_accepted + total_rejected);\n\tapplog(LOG_WARNING, \"Accepted shares: %d\", total_accepted);\n\tapplog(LOG_WARNING, \"Rejected shares: %d\", total_rejected);\n\tapplog(LOG_WARNING, \"Accepted difficulty shares: %1.f\", total_diff_accepted);\n\tapplog(LOG_WARNING, \"Rejected difficulty shares: %1.f\", total_diff_rejected);\n\tif (total_accepted || total_rejected)\n\t\tapplog(LOG_WARNING, \"Reject ratio: %.1f%%\", (double)(total_rejected * 100) / (double)(total_accepted + total_rejected));\n\tapplog(LOG_WARNING, \"Hardware errors: %d\", hw_errors);\n\tapplog(LOG_WARNING, \"Utility (accepted shares / min): %.2f/min\", utility);\n\tapplog(LOG_WARNING, \"Work Utility (diff1 shares solved / min): %.2f/min\\n\", work_util);\n\n\tapplog(LOG_WARNING, \"Stale submissions discarded due to new blocks: %d\", total_stale);\n\tapplog(LOG_WARNING, \"Unable to get work from server occasions: %d\", total_go);\n\tapplog(LOG_WARNING, \"Work items generated locally: %d\", local_work);\n\tapplog(LOG_WARNING, \"Submitting work remotely delay occasions: %d\", total_ro);\n\tapplog(LOG_WARNING, \"New blocks detected on network: %d\\n\", new_blocks);\n\n\tif (total_pools > 1) {\n\t\tfor (i = 0; i < total_pools; i++) {\n\t\t\tstruct pool *pool = pools[i];\n\n\t\t\tapplog(LOG_WARNING, \"Pool: %s\", pool->rpc_url);\n\t\t\tif (pool->solved)\n\t\t\t\tapplog(LOG_WARNING, \"SOLVED %d BLOCK%s!\", pool->solved, pool->solved > 1 ? \"S\" : \"\");\n\t\t\tapplog(LOG_WARNING, \" Share submissions: %d\", pool->accepted + pool->rejected);\n\t\t\tapplog(LOG_WARNING, \" Accepted shares: %d\", pool->accepted);\n\t\t\tapplog(LOG_WARNING, \" Rejected shares: %d\", pool->rejected);\n\t\t\tapplog(LOG_WARNING, \" Accepted difficulty shares: %1.f\", pool->diff_accepted);\n\t\t\tapplog(LOG_WARNING, \" Rejected difficulty shares: %1.f\", pool->diff_rejected);\n\t\t\tif (pool->accepted || pool->rejected)\n\t\t\t\tapplog(LOG_WARNING, \" Reject ratio: %.1f%%\", (double)(pool->rejected * 100) / (double)(pool->accepted + pool->rejected));\n\n\t\t\tapplog(LOG_WARNING, \" Stale submissions discarded due to new blocks: %d\", pool->stale_shares);\n\t\t\tapplog(LOG_WARNING, \" Unable to get work from server occasions: %d\", pool->getfail_occasions);\n\t\t\tapplog(LOG_WARNING, \" Submitting work remotely delay occasions: %d\\n\", pool->remotefail_occasions);\n\t\t}\n\t}\n\n\tapplog(LOG_WARNING, \"Summary of per device statistics:\\n\");\n\tfor (i = 0; i < total_devices; ++i) {\n\t\tstruct cgpu_info *cgpu = get_devices(i);\n\n\t\tlog_print_status(cgpu);\n\t}\n\n\tif (opt_shares) {\n\t\tapplog(LOG_WARNING, \"Mined %d accepted shares of %d requested\\n\", total_accepted, opt_shares);\n\t\tif (opt_shares > total_accepted)\n\t\t\tapplog(LOG_WARNING, \"WARNING - Mined only %d shares of %d requested.\", total_accepted, opt_shares);\n\t}\n\tapplog(LOG_WARNING, \" \");\n\n\tfflush(stderr);\n\tfflush(stdout);\n}\n\nstatic void clean_up(void)\n{\n#ifdef HAVE_OPENCL\n\tclear_adl(nDevs);\n#endif\n#ifdef HAVE_LIBUSB\n        libusb_exit(NULL);\n#endif\n\n\tcgtime(&total_tv_end);\n#ifdef HAVE_CURSES\n\tdisable_curses();\n#endif\n\tif (!opt_realquiet && successful_connect)\n\t\tprint_summary();\n\n\tcurl_global_cleanup();\n}\n\nvoid quit(int status, const char *format, ...)\n{\n\tif (format) {\n\t\tva_list ap;\n\t\tva_start(ap, format);\n\t\tvapplog(LOG_ERR, format, ap);\n\t\tva_end(ap);\n\t}\n\n\tclean_up();\n\n#if defined(unix)\n\tif (forkpid > 0) {\n\t\tkill(forkpid, SIGTERM);\n\t\tforkpid = 0;\n\t}\n#endif\n\n\texit(status);\n}\n\n#ifdef HAVE_CURSES\nchar *curses_input(const char *query)\n{\n\tchar *input;\n\n\techo();\n\tinput = malloc(255);\n\tif (!input)\n\t\tquit(1, \"Failed to malloc input\");\n\tleaveok(logwin, false);\n\twlogprint(\"%s:\\n\", query);\n\twgetnstr(logwin, input, 255);\n\tif (!strlen(input))\n\t\tstrcpy(input, \"-1\");\n\tleaveok(logwin, true);\n\tnoecho();\n\treturn input;\n}\n#endif\n\nstatic bool pools_active = false;\n\nstatic void *test_pool_thread(void *arg)\n{\n\tstruct pool *pool = (struct pool *)arg;\n\n\tif (pool_active(pool, false)) {\n\t\tpool_tset(pool, &pool->lagging);\n\t\tpool_tclear(pool, &pool->idle);\n\t\tbool first_pool = false;\n\n\t\tcg_wlock(&control_lock);\n\t\tif (!pools_active) {\n\t\t\tcurrentpool = pool;\n\t\t\tif (pool->pool_no != 0)\n\t\t\t\tfirst_pool = true;\n\t\t\tpools_active = true;\n\t\t}\n\t\tcg_wunlock(&control_lock);\n\n\t\tif (unlikely(first_pool))\n\t\t\tapplog(LOG_NOTICE, \"Switching to pool %d %s - first alive pool\", pool->pool_no, pool->rpc_url);\n\n\t\tpool_resus(pool);\n\t} else\n\t\tpool_died(pool);\n\n\treturn NULL;\n}\n\n/* Always returns true that the pool details were added unless we are not\n * live, implying this is the only pool being added, so if no pools are\n * active it returns false. */\nbool add_pool_details(struct pool *pool, bool live, char *url, char *user, char *pass)\n{\n\turl = get_proxy(url, pool);\n\n\tpool->rpc_url = url;\n\tpool->rpc_user = user;\n\tpool->rpc_pass = pass;\n\tpool->rpc_userpass = malloc(strlen(pool->rpc_user) + strlen(pool->rpc_pass) + 2);\n\tif (!pool->rpc_userpass)\n\t\tquit(1, \"Failed to malloc userpass\");\n\tsprintf(pool->rpc_userpass, \"%s:%s\", pool->rpc_user, pool->rpc_pass);\n\n\tpool->testing = true;\n\tpool->idle = true;\n\tenable_pool(pool);\n\n\tpthread_create(&pool->test_thread, NULL, test_pool_thread, (void *)pool);\n\tif (!live) {\n\t\tpthread_join(pool->test_thread, NULL);\n\t\tpool->testing = false;\n\t\treturn pools_active;\n\t}\n\treturn true;\n}\n\n#ifdef HAVE_CURSES\nstatic bool input_pool(bool live)\n{\n\tchar *url = NULL, *user = NULL, *pass = NULL;\n\tstruct pool *pool;\n\tbool ret = false;\n\n\timmedok(logwin, true);\n\twlogprint(\"Input server details.\\n\");\n\n\turl = curses_input(\"URL\");\n\tif (!url)\n\t\tgoto out;\n\n\tuser = curses_input(\"Username\");\n\tif (!user)\n\t\tgoto out;\n\n\tpass = curses_input(\"Password\");\n\tif (!pass)\n\t\tgoto out;\n\n\tpool = add_pool();\n\n\tif (!detect_stratum(pool, url) && strncmp(url, \"http://\", 7) &&\n\t    strncmp(url, \"https://\", 8)) {\n\t\tchar *httpinput;\n\n\t\thttpinput = malloc(256);\n\t\tif (!httpinput)\n\t\t\tquit(1, \"Failed to malloc httpinput\");\n\t\tstrcpy(httpinput, \"http://\");\n\t\tstrncat(httpinput, url, 248);\n\t\tfree(url);\n\t\turl = httpinput;\n\t}\n\n\tret = add_pool_details(pool, live, url, user, pass);\nout:\n\timmedok(logwin, false);\n\n\tif (!ret) {\n\t\tif (url)\n\t\t\tfree(url);\n\t\tif (user)\n\t\t\tfree(user);\n\t\tif (pass)\n\t\t\tfree(pass);\n\t}\n\treturn ret;\n}\n#endif\n\n#if defined(unix)\nstatic void fork_monitor()\n{\n\t// Make a pipe: [readFD, writeFD]\n\tint pfd[2];\n\tint r = pipe(pfd);\n\n\tif (r < 0) {\n\t\tperror(\"pipe - failed to create pipe for --monitor\");\n\t\texit(1);\n\t}\n\n\t// Make stderr write end of pipe\n\tfflush(stderr);\n\tr = dup2(pfd[1], 2);\n\tif (r < 0) {\n\t\tperror(\"dup2 - failed to alias stderr to write end of pipe for --monitor\");\n\t\texit(1);\n\t}\n\tr = close(pfd[1]);\n\tif (r < 0) {\n\t\tperror(\"close - failed to close write end of pipe for --monitor\");\n\t\texit(1);\n\t}\n\n\t// Don't allow a dying monitor to kill the main process\n\tsighandler_t sr0 = signal(SIGPIPE, SIG_IGN);\n\tsighandler_t sr1 = signal(SIGPIPE, SIG_IGN);\n\tif (SIG_ERR == sr0 || SIG_ERR == sr1) {\n\t\tperror(\"signal - failed to edit signal mask for --monitor\");\n\t\texit(1);\n\t}\n\n\t// Fork a child process\n\tforkpid = fork();\n\tif (forkpid < 0) {\n\t\tperror(\"fork - failed to fork child process for --monitor\");\n\t\texit(1);\n\t}\n\n\t// Child: launch monitor command\n\tif (0 == forkpid) {\n\t\t// Make stdin read end of pipe\n\t\tr = dup2(pfd[0], 0);\n\t\tif (r < 0) {\n\t\t\tperror(\"dup2 - in child, failed to alias read end of pipe to stdin for --monitor\");\n\t\t\texit(1);\n\t\t}\n\t\tclose(pfd[0]);\n\t\tif (r < 0) {\n\t\t\tperror(\"close - in child, failed to close read end of  pipe for --monitor\");\n\t\t\texit(1);\n\t\t}\n\n\t\t// Launch user specified command\n\t\texecl(\"/bin/bash\", \"/bin/bash\", \"-c\", opt_stderr_cmd, (char*)NULL);\n\t\tperror(\"execl - in child failed to exec user specified command for --monitor\");\n\t\texit(1);\n\t}\n\n\t// Parent: clean up unused fds and bail\n\tr = close(pfd[0]);\n\tif (r < 0) {\n\t\tperror(\"close - failed to close read end of pipe for --monitor\");\n\t\texit(1);\n\t}\n}\n#endif // defined(unix)\n\n#ifdef HAVE_CURSES\nvoid enable_curses(void) {\n\tint x,y;\n\n\tlock_curses();\n\tif (curses_active) {\n\t\tunlock_curses();\n\t\treturn;\n\t}\n\n\tmainwin = initscr();\n\tgetmaxyx(mainwin, y, x);\n\tstatuswin = newwin(logstart, x, 0, 0);\n\tleaveok(statuswin, true);\n\tlogwin = newwin(y - logcursor, 0, logcursor, 0);\n\tidlok(logwin, true);\n\tscrollok(logwin, true);\n\tleaveok(logwin, true);\n\tcbreak();\n\tnoecho();\n\tcurses_active = true;\n\tstatusy = logstart;\n\tunlock_curses();\n}\n#endif\n\n#ifdef USE_BFLSC\nextern struct device_drv bflsc_drv;\n#endif\n\n#ifdef USE_BITFORCE\nextern struct device_drv bitforce_drv;\n#endif\n\n#ifdef USE_ICARUS\nextern struct device_drv icarus_drv;\n#endif\n\n#ifdef USE_AVALON\nextern struct device_drv avalon_drv;\n#endif\n\n#ifdef USE_MODMINER\nextern struct device_drv modminer_drv;\n#endif\n\n#ifdef USE_ZTEX\nextern struct device_drv ztex_drv;\n#endif\n\nstatic int cgminer_id_count = 0;\n\n/* Various noop functions for drivers that don't support or need their\n * variants. */\nstatic void noop_reinit_device(struct cgpu_info __maybe_unused *cgpu)\n{\n}\n\nvoid blank_get_statline_before(char *buf, struct cgpu_info __maybe_unused *cgpu)\n{\n\ttailsprintf(buf, \"               | \");\n}\n\nstatic void noop_get_statline(char __maybe_unused *buf, struct cgpu_info __maybe_unused *cgpu)\n{\n}\n\nstatic bool noop_get_stats(struct cgpu_info __maybe_unused *cgpu)\n{\n\treturn true;\n}\n\nstatic bool noop_thread_prepare(struct thr_info __maybe_unused *thr)\n{\n\treturn true;\n}\n\nstatic uint64_t noop_can_limit_work(struct thr_info __maybe_unused *thr)\n{\n\treturn 0xffffffff;\n}\n\nstatic bool noop_thread_init(struct thr_info __maybe_unused *thr)\n{\n\treturn true;\n}\n\nstatic bool noop_prepare_work(struct thr_info __maybe_unused *thr, struct work __maybe_unused *work)\n{\n\treturn true;\n}\n\nstatic void noop_hw_error(struct thr_info __maybe_unused *thr)\n{\n}\n\nstatic void noop_thread_shutdown(struct thr_info __maybe_unused *thr)\n{\n}\n\nstatic void noop_thread_enable(struct thr_info __maybe_unused *thr)\n{\n}\n\n#define noop_flush_work noop_reinit_device\n#define noop_queue_full noop_get_stats\n\n/* Fill missing driver drv functions with noops */\nvoid fill_device_drv(struct cgpu_info *cgpu)\n{\n\tstruct device_drv *drv = cgpu->drv;\n\n\tif (!drv->reinit_device)\n\t\tdrv->reinit_device = &noop_reinit_device;\n\tif (!drv->get_statline_before)\n\t\tdrv->get_statline_before = &blank_get_statline_before;\n\tif (!drv->get_statline)\n\t\tdrv->get_statline = &noop_get_statline;\n\tif (!drv->get_stats)\n\t\tdrv->get_stats = &noop_get_stats;\n\tif (!drv->thread_prepare)\n\t\tdrv->thread_prepare = &noop_thread_prepare;\n\tif (!drv->can_limit_work)\n\t\tdrv->can_limit_work = &noop_can_limit_work;\n\tif (!drv->thread_init)\n\t\tdrv->thread_init = &noop_thread_init;\n\tif (!drv->prepare_work)\n\t\tdrv->prepare_work = &noop_prepare_work;\n\tif (!drv->hw_error)\n\t\tdrv->hw_error = &noop_hw_error;\n\tif (!drv->thread_shutdown)\n\t\tdrv->thread_shutdown = &noop_thread_shutdown;\n\tif (!drv->thread_enable)\n\t\tdrv->thread_enable = &noop_thread_enable;\n\tif (!drv->hash_work)\n\t\tdrv->hash_work = &hash_sole_work;\n\tif (!drv->flush_work)\n\t\tdrv->flush_work = &noop_flush_work;\n\tif (!drv->queue_full)\n\t\tdrv->queue_full = &noop_queue_full;\n\tif (!drv->max_diff)\n\t\tdrv->max_diff = 1;\n\tif (!drv->working_diff)\n\t\tdrv->working_diff = 1;\n}\n\nvoid enable_device(struct cgpu_info *cgpu)\n{\n\tcgpu->deven = DEV_ENABLED;\n\n\twr_lock(&devices_lock);\n\tdevices[cgpu->cgminer_id = cgminer_id_count++] = cgpu;\n\twr_unlock(&devices_lock);\n\n\tif (hotplug_mode) {\n\t\tnew_threads += cgpu->threads;\n#ifdef HAVE_CURSES\n\t\tadj_width(mining_threads + new_threads, &dev_width);\n#endif\n\t} else {\n\t\tmining_threads += cgpu->threads;\n#ifdef HAVE_CURSES\n\t\tadj_width(mining_threads, &dev_width);\n#endif\n\t}\n#ifdef HAVE_OPENCL\n\tif (cgpu->drv->drv_id == DRIVER_OPENCL) {\n\t\tgpu_threads += cgpu->threads;\n\t}\n#endif\n\tfill_device_drv(cgpu);\n\n\trwlock_init(&cgpu->qlock);\n\tcgpu->queued_work = NULL;\n}\n\nstruct _cgpu_devid_counter {\n\tchar name[4];\n\tint lastid;\n\tUT_hash_handle hh;\n};\n\nbool add_cgpu(struct cgpu_info *cgpu)\n{\n\tstatic struct _cgpu_devid_counter *devids = NULL;\n\tstruct _cgpu_devid_counter *d;\n\t\n\tHASH_FIND_STR(devids, cgpu->drv->name, d);\n\tif (d)\n\t\tcgpu->device_id = ++d->lastid;\n\telse {\n\t\td = malloc(sizeof(*d));\n\t\tmemcpy(d->name, cgpu->drv->name, sizeof(d->name));\n\t\tcgpu->device_id = d->lastid = 0;\n\t\tHASH_ADD_STR(devids, name, d);\n\t}\n\n\twr_lock(&devices_lock);\n\tdevices = realloc(devices, sizeof(struct cgpu_info *) * (total_devices + new_devices + 2));\n\twr_unlock(&devices_lock);\n\n\tmutex_lock(&stats_lock);\n\tcgpu->last_device_valid_work = time(NULL);\n\tmutex_unlock(&stats_lock);\n\n\tif (hotplug_mode)\n\t\tdevices[total_devices + new_devices++] = cgpu;\n\telse\n\t\tdevices[total_devices++] = cgpu;\n\treturn true;\n}\n\nstruct device_drv *copy_drv(struct device_drv *drv)\n{\n\tstruct device_drv *copy;\n\tchar buf[100];\n\n\tif (unlikely(!(copy = malloc(sizeof(*copy))))) {\n\t\tsprintf(buf, \"Failed to allocate device_drv copy of %s (%s)\",\n\t\t\t\tdrv->name, drv->copy ? \"copy\" : \"original\");\n\t\tquit(1, buf);\n\t}\n\tmemcpy(copy, drv, sizeof(*copy));\n\tcopy->copy = true;\n\treturn copy;\n}\n\n#ifdef USE_USBUTILS\nstatic void hotplug_process()\n{\n\tstruct thr_info *thr;\n\tint i, j;\n\n\tfor (i = 0; i < new_devices; i++) {\n\t\tstruct cgpu_info *cgpu = devices[total_devices + i];\n\t\tenable_device(cgpu);\n\t\tcgpu->cgminer_stats.getwork_wait_min.tv_sec = MIN_SEC_UNSET;\n\t\tcgpu->rolling = cgpu->total_mhashes = 0;\n\t}\n\n\twr_lock(&mining_thr_lock);\n\tmining_thr = realloc(mining_thr, sizeof(thr) * (mining_threads + new_threads + 1));\n\twr_unlock(&mining_thr_lock);\n\n\tif (!mining_thr)\n\t\tquit(1, \"Failed to hotplug realloc mining_thr\");\n\tfor (i = 0; i < new_threads; i++) {\n\t\tmining_thr[mining_threads + i] = calloc(1, sizeof(*thr));\n\t\tif (!mining_thr[mining_threads + i])\n\t\t\tquit(1, \"Failed to hotplug calloc mining_thr[%d]\", i);\n\t}\n\n\t// Start threads\n\tfor (i = 0; i < new_devices; ++i) {\n\t\tstruct cgpu_info *cgpu = devices[total_devices];\n\t\tcgpu->thr = malloc(sizeof(*cgpu->thr) * (cgpu->threads+1));\n\t\tcgpu->thr[cgpu->threads] = NULL;\n\t\tcgpu->status = LIFE_INIT;\n\n\t\tfor (j = 0; j < cgpu->threads; ++j) {\n\t\t\tthr = get_thread(mining_threads);\n\t\t\tthr->id = mining_threads;\n\t\t\tthr->cgpu = cgpu;\n\t\t\tthr->device_thread = j;\n\n\t\t\tthr->q = tq_new();\n\t\t\tif (!thr->q)\n\t\t\t\tquit(1, \"tq_new hotplug failed in starting %s%d mining thread (#%d)\", cgpu->drv->name, cgpu->device_id, total_devices);\n\n\t\t\t/* Enable threads for devices set not to mine but disable\n\t\t\t * their queue in case we wish to enable them later */\n\t\t\tif (cgpu->deven != DEV_DISABLED) {\n\t\t\t\tapplog(LOG_DEBUG, \"Pushing hotplug ping to thread %d\", thr->id);\n\t\t\t\ttq_push(thr->q, &ping);\n\t\t\t}\n\n\t\t\tif (cgpu->drv->thread_prepare && !cgpu->drv->thread_prepare(thr))\n\t\t\t\tcontinue;\n\n\t\t\tthread_reportout(thr);\n\n\t\t\tif (unlikely(thr_info_create(thr, NULL, miner_thread, thr)))\n\t\t\t\tquit(1, \"hotplug thread %d create failed\", thr->id);\n\n\t\t\tcgpu->thr[j] = thr;\n\n\t\t\tmining_threads++;\n\t\t}\n\t\ttotal_devices++;\n\t\tapplog(LOG_WARNING, \"Hotplug: %s added %s %i\", cgpu->drv->dname, cgpu->drv->name, cgpu->device_id);\n\t}\n}\n\nstatic void *hotplug_thread(void __maybe_unused *userdata)\n{\n\tpthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);\n\n\tRenameThread(\"hotplug\");\n\n\thotplug_mode = true;\n\n\tnmsleep(5000);\n\n\twhile (0x2a) {\n// Version 0.1 just add the devices on - worry about using nodev later\n\n\t\tif (hotplug_time == 0)\n\t\t\tnmsleep(5000);\n\t\telse {\n\t\t\tnew_devices = 0;\n\t\t\tnew_threads = 0;\n\n#ifdef USE_BFLSC\n\t\t\tbflsc_drv.drv_detect();\n#endif\n\n#ifdef USE_BITFORCE\n\t\t\tbitforce_drv.drv_detect();\n#endif\n\n#ifdef USE_MODMINER\n\t\t\tmodminer_drv.drv_detect();\n#endif\n\n\t\t\tif (new_devices)\n\t\t\t\thotplug_process();\n\n\t\t\t// hotplug_time >0 && <=9999\n\t\t\tnmsleep(hotplug_time * 1000);\n\t\t}\n\t}\n\n\treturn NULL;\n}\n#endif\n\nstatic void probe_pools(void)\n{\n\tint i;\n\n\tfor (i = 0; i < total_pools; i++) {\n\t\tstruct pool *pool = pools[i];\n\n\t\tpool->testing = true;\n\t\tpthread_create(&pool->test_thread, NULL, test_pool_thread, (void *)pool);\n\t}\n}\n\nint main(int argc, char *argv[])\n{\n\tstruct sigaction handler;\n\tstruct thr_info *thr;\n\tstruct block *block;\n\tunsigned int k;\n\tint i, j;\n\tchar *s;\n\n\t/* This dangerous functions tramples random dynamically allocated\n\t * variables so do it before anything at all */\n\tif (unlikely(curl_global_init(CURL_GLOBAL_ALL)))\n\t\tquit(1, \"Failed to curl_global_init\");\n\n\tinitial_args = malloc(sizeof(char *) * (argc + 1));\n\tfor  (i = 0; i < argc; i++)\n\t\tinitial_args[i] = strdup(argv[i]);\n\tinitial_args[argc] = NULL;\n\n#ifdef HAVE_LIBUSB\n\tint err = libusb_init(NULL);\n\tif (err) {\n\t\tfprintf(stderr, \"libusb_init() failed err %d\", err);\n\t\tfflush(stderr);\n\t\tquit(1, \"libusb_init() failed\");\n\t}\n#ifdef USE_USBUTILS\n\tmutex_init(&cgusb_lock);\n#endif\n#endif\n\n\tmutex_init(&hash_lock);\n\tmutex_init(&console_lock);\n\tcglock_init(&control_lock);\n\tmutex_init(&stats_lock);\n\tmutex_init(&sharelog_lock);\n\tcglock_init(&ch_lock);\n\tmutex_init(&sshare_lock);\n\trwlock_init(&blk_lock);\n\trwlock_init(&netacc_lock);\n\trwlock_init(&mining_thr_lock);\n\trwlock_init(&devices_lock);\n\n\tmutex_init(&lp_lock);\n\tif (unlikely(pthread_cond_init(&lp_cond, NULL)))\n\t\tquit(1, \"Failed to pthread_cond_init lp_cond\");\n\n\tmutex_init(&restart_lock);\n\tif (unlikely(pthread_cond_init(&restart_cond, NULL)))\n\t\tquit(1, \"Failed to pthread_cond_init restart_cond\");\n\n\tif (unlikely(pthread_cond_init(&gws_cond, NULL)))\n\t\tquit(1, \"Failed to pthread_cond_init gws_cond\");\n\n\tsprintf(packagename, \"%s %s\", PACKAGE, VERSION);\n\n\thandler.sa_handler = &sighandler;\n\thandler.sa_flags = 0;\n\tsigemptyset(&handler.sa_mask);\n\tsigaction(SIGTERM, &handler, &termhandler);\n\tsigaction(SIGINT, &handler, &inthandler);\n#ifndef WIN32\n\tsignal(SIGPIPE, SIG_IGN);\n#endif\n\topt_kernel_path = alloca(PATH_MAX);\n\tstrcpy(opt_kernel_path, CGMINER_PREFIX);\n\tcgminer_path = alloca(PATH_MAX);\n\ts = strdup(argv[0]);\n\tstrcpy(cgminer_path, dirname(s));\n\tfree(s);\n\tstrcat(cgminer_path, \"/\");\n\n\tdevcursor = 8;\n\tlogstart = devcursor + 1;\n\tlogcursor = logstart + 1;\n\n\tblock = calloc(sizeof(struct block), 1);\n\tif (unlikely(!block))\n\t\tquit (1, \"main OOM\");\n\tfor (i = 0; i < 36; i++)\n\t\tstrcat(block->hash, \"0\");\n\tHASH_ADD_STR(blocks, hash, block);\n\tstrcpy(current_block, block->hash);\n\n\tINIT_LIST_HEAD(&scan_devices);\n\n#ifdef HAVE_OPENCL\n\tmemset(gpus, 0, sizeof(gpus));\n\tfor (i = 0; i < MAX_GPUDEVICES; i++)\n\t\tgpus[i].dynamic = true;\n#endif\n\n\t/* parse command line */\n\topt_register_table(opt_config_table,\n\t\t\t   \"Options for both config file and command line\");\n\topt_register_table(opt_cmdline_table,\n\t\t\t   \"Options for command line only\");\n\n\topt_parse(&argc, argv, applog_and_exit);\n\tif (argc != 1)\n\t\tquit(1, \"Unexpected extra commandline arguments\");\n\n\tif (!config_loaded)\n\t\tload_default_config();\n\n\tif (opt_benchmark) {\n\t\tstruct pool *pool;\n\n\t\tpool = add_pool();\n\t\tpool->rpc_url = malloc(255);\n\t\tstrcpy(pool->rpc_url, \"Benchmark\");\n\t\tpool->rpc_user = pool->rpc_url;\n\t\tpool->rpc_pass = pool->rpc_url;\n\t\tenable_pool(pool);\n\t\tpool->idle = false;\n\t\tsuccessful_connect = true;\n\t}\n\n#ifdef HAVE_CURSES\n\tif (opt_realquiet || devices_enabled == -1)\n\t\tuse_curses = false;\n\n\tif (use_curses)\n\t\tenable_curses();\n#endif\n\n\tapplog(LOG_WARNING, \"Started %s\", packagename);\n\tif (cnfbuf) {\n\t\tapplog(LOG_NOTICE, \"Loaded configuration file %s\", cnfbuf);\n\t\tswitch (fileconf_load) {\n\t\t\tcase 0:\n\t\t\t\tapplog(LOG_WARNING, \"Fatal JSON error in configuration file.\");\n\t\t\t\tapplog(LOG_WARNING, \"Configuration file could not be used.\");\n\t\t\t\tbreak;\n\t\t\tcase -1:\n\t\t\t\tapplog(LOG_WARNING, \"Error in configuration file, partially loaded.\");\n\t\t\t\tif (use_curses)\n\t\t\t\t\tapplog(LOG_WARNING, \"Start cgminer with -T to see what failed to load.\");\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t\tfree(cnfbuf);\n\t\tcnfbuf = NULL;\n\t}\n\n\tstrcat(opt_kernel_path, \"/\");\n\n\tif (want_per_device_stats)\n\t\topt_log_output = true;\n\n\t/* Use a shorter scantime for scrypt */\n\tif (opt_scantime < 0)\n\t\topt_scantime = opt_scrypt ? 30 : 60;\n#ifdef USE_USBUTILS\n\tusb_initialise();\n#endif\n\n#ifdef HAVE_OPENCL\n\tif (!opt_nogpu)\n\t\topencl_drv.drv_detect();\n\tgpu_threads = 0;\n#endif\n\n#ifdef USE_ICARUS\n\t// if (!opt_scrypt)\t\t// KRAMBLE\n\t\ticarus_drv.drv_detect();\n#endif\n\n#ifdef USE_AVALON\n\tif (!opt_scrypt)\n\t\tavalon_drv.drv_detect();\n#endif\n\n#ifdef USE_BFLSC\n\tif (!opt_scrypt)\n\t\tbflsc_drv.drv_detect();\n#endif\n\n#ifdef USE_BITFORCE\n\tif (!opt_scrypt)\n\t\tbitforce_drv.drv_detect();\n#endif\n\n#ifdef USE_MODMINER\n\tif (!opt_scrypt)\n\t\tmodminer_drv.drv_detect();\n#endif\n\n#ifdef USE_ZTEX\n\t// if (!opt_scrypt)\t\t// KRAMBLE\n\t\tztex_drv.drv_detect();\n#endif\n\n\tif (devices_enabled == -1) {\n\t\tapplog(LOG_ERR, \"Devices detected:\");\n\t\tfor (i = 0; i < total_devices; ++i) {\n\t\t\tstruct cgpu_info *cgpu = devices[i];\n\t\t\tif (cgpu->name)\n\t\t\t\tapplog(LOG_ERR, \" %2d. %s %d: %s (driver: %s)\", i, cgpu->drv->name, cgpu->device_id, cgpu->name, cgpu->drv->dname);\n\t\t\telse\n\t\t\t\tapplog(LOG_ERR, \" %2d. %s %d (driver: %s)\", i, cgpu->drv->name, cgpu->device_id, cgpu->drv->dname);\n\t\t}\n\t\tquit(0, \"%d devices listed\", total_devices);\n\t}\n\n\tmining_threads = 0;\n\tif (devices_enabled) {\n\t\tfor (i = 0; i < (int)(sizeof(devices_enabled) * 8) - 1; ++i) {\n\t\t\tif (devices_enabled & (1 << i)) {\n\t\t\t\tif (i >= total_devices)\n\t\t\t\t\tquit (1, \"Command line options set a device that doesn't exist\");\n\t\t\t\tenable_device(devices[i]);\n\t\t\t} else if (i < total_devices) {\n\t\t\t\tif (!opt_removedisabled)\n\t\t\t\t\tenable_device(devices[i]);\n\t\t\t\tdevices[i]->deven = DEV_DISABLED;\n\t\t\t}\n\t\t}\n\t\ttotal_devices = cgminer_id_count;\n\t} else {\n\t\tfor (i = 0; i < total_devices; ++i)\n\t\t\tenable_device(devices[i]);\n\t}\n\n#ifdef USE_USBUTILS\n\tif (!total_devices) {\n\t\tapplog(LOG_WARNING, \"No devices detected!\");\n\t\tapplog(LOG_WARNING, \"Waiting for USB hotplug devices or press q to quit\");\n\t}\n#else\n\tif (!total_devices)\n\t\tquit(1, \"All devices disabled, cannot mine!\");\n#endif\n\n\tstart_devices = total_devices;\n\n\tload_temp_cutoffs();\n\n\tfor (i = 0; i < total_devices; ++i)\n\t\tdevices[i]->cgminer_stats.getwork_wait_min.tv_sec = MIN_SEC_UNSET;\n\n\tif (!opt_compact) {\n\t\tlogstart += total_devices;\n\t\tlogcursor = logstart + 1;\n#ifdef HAVE_CURSES\n\t\tcheck_winsizes();\n#endif\n\t}\n\n\tif (!total_pools) {\n\t\tapplog(LOG_WARNING, \"Need to specify at least one pool server.\");\n#ifdef HAVE_CURSES\n\t\tif (!use_curses || !input_pool(false))\n#endif\n\t\t\tquit(1, \"Pool setup failed\");\n\t}\n\n\tfor (i = 0; i < total_pools; i++) {\n\t\tstruct pool *pool = pools[i];\n\n\t\tpool->cgminer_stats.getwork_wait_min.tv_sec = MIN_SEC_UNSET;\n\t\tpool->cgminer_pool_stats.getwork_wait_min.tv_sec = MIN_SEC_UNSET;\n\n\t\tif (!pool->rpc_userpass) {\n\t\t\tif (!pool->rpc_user || !pool->rpc_pass)\n\t\t\t\tquit(1, \"No login credentials supplied for pool %u %s\", i, pool->rpc_url);\n\t\t\tpool->rpc_userpass = malloc(strlen(pool->rpc_user) + strlen(pool->rpc_pass) + 2);\n\t\t\tif (!pool->rpc_userpass)\n\t\t\t\tquit(1, \"Failed to malloc userpass\");\n\t\t\tsprintf(pool->rpc_userpass, \"%s:%s\", pool->rpc_user, pool->rpc_pass);\n\t\t}\n\t}\n\t/* Set the currentpool to pool 0 */\n\tcurrentpool = pools[0];\n\n#ifdef HAVE_SYSLOG_H\n\tif (use_syslog)\n\t\topenlog(PACKAGE, LOG_PID, LOG_USER);\n#endif\n\n\t#if defined(unix)\n\t\tif (opt_stderr_cmd)\n\t\t\tfork_monitor();\n\t#endif // defined(unix)\n\n\tmining_thr = calloc(mining_threads, sizeof(thr));\n\tif (!mining_thr)\n\t\tquit(1, \"Failed to calloc mining_thr\");\n\tfor (i = 0; i < mining_threads; i++) {\n\t\tmining_thr[i] = calloc(1, sizeof(*thr));\n\t\tif (!mining_thr[i])\n\t\t\tquit(1, \"Failed to calloc mining_thr[%d]\", i);\n\t}\n\n\ttotal_control_threads = 8;\n\tcontrol_thr = calloc(total_control_threads, sizeof(*thr));\n\tif (!control_thr)\n\t\tquit(1, \"Failed to calloc control_thr\");\n\n\tgwsched_thr_id = 0;\n\tstage_thr_id = 1;\n\tthr = &control_thr[stage_thr_id];\n\tthr->q = tq_new();\n\tif (!thr->q)\n\t\tquit(1, \"Failed to tq_new\");\n\t/* start stage thread */\n\tif (thr_info_create(thr, NULL, stage_thread, thr))\n\t\tquit(1, \"stage thread create failed\");\n\tpthread_detach(thr->pth);\n\n\t/* Create a unique get work queue */\n\tgetq = tq_new();\n\tif (!getq)\n\t\tquit(1, \"Failed to create getq\");\n\t/* We use the getq mutex as the staged lock */\n\tstgd_lock = &getq->mutex;\n\n\tif (opt_benchmark)\n\t\tgoto begin_bench;\n\n\tfor (i = 0; i < total_pools; i++) {\n\t\tstruct pool *pool  = pools[i];\n\n\t\tenable_pool(pool);\n\t\tpool->idle = true;\n\t}\n\n\tapplog(LOG_NOTICE, \"Probing for an alive pool\");\n\tdo {\n\t\tint slept = 0;\n\n\t\t/* Look for at least one active pool before starting */\n\t\tprobe_pools();\n\t\tdo {\n\t\t\tsleep(1);\n\t\t\tslept++;\n\t\t} while (!pools_active && slept < 60);\n\n\t\tif (!pools_active) {\n\t\t\tapplog(LOG_ERR, \"No servers were found that could be used to get work from.\");\n\t\t\tapplog(LOG_ERR, \"Please check the details from the list below of the servers you have input\");\n\t\t\tapplog(LOG_ERR, \"Most likely you have input the wrong URL, forgotten to add a port, or have not set up workers\");\n\t\t\tfor (i = 0; i < total_pools; i++) {\n\t\t\t\tstruct pool *pool;\n\n\t\t\t\tpool = pools[i];\n\t\t\t\tapplog(LOG_WARNING, \"Pool: %d  URL: %s  User: %s  Password: %s\",\n\t\t\t\t       i, pool->rpc_url, pool->rpc_user, pool->rpc_pass);\n\t\t\t}\n#ifdef HAVE_CURSES\n\t\t\tif (use_curses) {\n\t\t\t\thalfdelay(150);\n\t\t\t\tapplog(LOG_ERR, \"Press any key to exit, or cgminer will try again in 15s.\");\n\t\t\t\tif (getch() != ERR)\n\t\t\t\t\tquit(0, \"No servers could be used! Exiting.\");\n\t\t\t\tcbreak();\n\t\t\t} else\n#endif\n\t\t\t\tquit(0, \"No servers could be used! Exiting.\");\n\t\t}\n\t} while (!pools_active);\n\nbegin_bench:\n\ttotal_mhashes_done = 0;\n\tfor (i = 0; i < total_devices; i++) {\n\t\tstruct cgpu_info *cgpu = devices[i];\n\n\t\tcgpu->rolling = cgpu->total_mhashes = 0;\n\t}\n\t\n\tcgtime(&total_tv_start);\n\tcgtime(&total_tv_end);\n\tget_datestamp(datestamp, &total_tv_start);\n\n\t// Start threads\n\tk = 0;\n\tfor (i = 0; i < total_devices; ++i) {\n\t\tstruct cgpu_info *cgpu = devices[i];\n\t\tcgpu->thr = malloc(sizeof(*cgpu->thr) * (cgpu->threads+1));\n\t\tcgpu->thr[cgpu->threads] = NULL;\n\t\tcgpu->status = LIFE_INIT;\n\n\t\tfor (j = 0; j < cgpu->threads; ++j, ++k) {\n\t\t\tthr = get_thread(k);\n\t\t\tthr->id = k;\n\t\t\tthr->cgpu = cgpu;\n\t\t\tthr->device_thread = j;\n\n\t\t\tthr->q = tq_new();\n\t\t\tif (!thr->q)\n\t\t\t\tquit(1, \"tq_new failed in starting %s%d mining thread (#%d)\", cgpu->drv->name, cgpu->device_id, i);\n\n\t\t\t/* Enable threads for devices set not to mine but disable\n\t\t\t * their queue in case we wish to enable them later */\n\t\t\tif (cgpu->deven != DEV_DISABLED) {\n\t\t\t\tapplog(LOG_DEBUG, \"Pushing ping to thread %d\", thr->id);\n\n\t\t\t\ttq_push(thr->q, &ping);\n\t\t\t}\n\n\t\t\tif (!cgpu->drv->thread_prepare(thr))\n\t\t\t\tcontinue;\n\n\t\t\tthread_reportout(thr);\n\n\t\t\tif (unlikely(thr_info_create(thr, NULL, miner_thread, thr)))\n\t\t\t\tquit(1, \"thread %d create failed\", thr->id);\n\n\t\t\tcgpu->thr[j] = thr;\n\t\t}\n\t}\n\n#ifdef HAVE_OPENCL\n\tapplog(LOG_INFO, \"%d gpu miner threads started\", gpu_threads);\n\tfor (i = 0; i < nDevs; i++)\n\t\tpause_dynamic_threads(i);\n#endif\n\n\tcgtime(&total_tv_start);\n\tcgtime(&total_tv_end);\n\n\twatchpool_thr_id = 2;\n\tthr = &control_thr[watchpool_thr_id];\n\t/* start watchpool thread */\n\tif (thr_info_create(thr, NULL, watchpool_thread, NULL))\n\t\tquit(1, \"watchpool thread create failed\");\n\tpthread_detach(thr->pth);\n\n\twatchdog_thr_id = 3;\n\tthr = &control_thr[watchdog_thr_id];\n\t/* start watchdog thread */\n\tif (thr_info_create(thr, NULL, watchdog_thread, NULL))\n\t\tquit(1, \"watchdog thread create failed\");\n\tpthread_detach(thr->pth);\n\n#ifdef HAVE_OPENCL\n\t/* Create reinit gpu thread */\n\tgpur_thr_id = 4;\n\tthr = &control_thr[gpur_thr_id];\n\tthr->q = tq_new();\n\tif (!thr->q)\n\t\tquit(1, \"tq_new failed for gpur_thr_id\");\n\tif (thr_info_create(thr, NULL, reinit_gpu, thr))\n\t\tquit(1, \"reinit_gpu thread create failed\");\n#endif\t\n\n\t/* Create API socket thread */\n\tapi_thr_id = 5;\n\tthr = &control_thr[api_thr_id];\n\tif (thr_info_create(thr, NULL, api_thread, thr))\n\t\tquit(1, \"API thread create failed\");\n\n#ifdef USE_USBUTILS\n\tif (!opt_scrypt) {\n\t\thotplug_thr_id = 6;\n\t\tthr = &control_thr[hotplug_thr_id];\n\t\tif (thr_info_create(thr, NULL, hotplug_thread, thr))\n\t\t\tquit(1, \"hotplug thread create failed\");\n\t\tpthread_detach(thr->pth);\n\t}\n#endif\n\n#ifdef HAVE_CURSES\n\t/* Create curses input thread for keyboard input. Create this last so\n\t * that we know all threads are created since this can call kill_work\n\t * to try and shut down all previous threads. */\n\tinput_thr_id = 7;\n\tthr = &control_thr[input_thr_id];\n\tif (thr_info_create(thr, NULL, input_thread, thr))\n\t\tquit(1, \"input thread create failed\");\n\tpthread_detach(thr->pth);\n#endif\n\n\t/* Just to be sure */\n\tif (total_control_threads != 8)\n\t\tquit(1, \"incorrect total_control_threads (%d) should be 8\", total_control_threads);\n\n\t/* Once everything is set up, main() becomes the getwork scheduler */\n\twhile (42) {\n\t\tint ts, max_staged = opt_queue;\n\t\tstruct pool *pool, *cp;\n\t\tbool lagging = false;\n\t\tstruct curl_ent *ce;\n\t\tstruct work *work;\n\n\t\tcp = current_pool();\n\n\t\t/* If the primary pool is a getwork pool and cannot roll work,\n\t\t * try to stage one extra work per mining thread */\n\t\tif (!cp->has_stratum && !cp->has_gbt && !staged_rollable)\n\t\t\tmax_staged += mining_threads;\n\n\t\tmutex_lock(stgd_lock);\n\t\tts = __total_staged();\n\n\t\tif (!cp->has_stratum && !cp->has_gbt && !ts && !opt_fail_only)\n\t\t\tlagging = true;\n\n\t\t/* Wait until hash_pop tells us we need to create more work */\n\t\tif (ts > max_staged) {\n\t\t\tpthread_cond_wait(&gws_cond, stgd_lock);\n\t\t\tts = __total_staged();\n\t\t}\n\t\tmutex_unlock(stgd_lock);\n\n\t\tif (ts > max_staged)\n\t\t\tcontinue;\n\n\t\twork = make_work();\n\n\t\tif (lagging && !pool_tset(cp, &cp->lagging)) {\n\t\t\tapplog(LOG_WARNING, \"Pool %d not providing work fast enough\", cp->pool_no);\n\t\t\tcp->getfail_occasions++;\n\t\t\ttotal_go++;\n\t\t}\n\t\tpool = select_pool(lagging);\nretry:\n\t\tif (pool->has_stratum) {\n\t\t\twhile (!pool->stratum_active || !pool->stratum_notify) {\n\t\t\t\tstruct pool *altpool = select_pool(true);\n\n\t\t\t\tnmsleep(5000);\n\t\t\t\tif (altpool != pool) {\n\t\t\t\t\tpool = altpool;\n\t\t\t\t\tgoto retry;\n\t\t\t\t}\n\t\t\t}\n\t\t\tgen_stratum_work(pool, work);\n\t\t\tapplog(LOG_DEBUG, \"Generated stratum work\");\n\t\t\tstage_work(work);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (pool->has_gbt) {\n\t\t\twhile (pool->idle) {\n\t\t\t\tstruct pool *altpool = select_pool(true);\n\n\t\t\t\tnmsleep(5000);\n\t\t\t\tif (altpool != pool) {\n\t\t\t\t\tpool = altpool;\n\t\t\t\t\tgoto retry;\n\t\t\t\t}\n\t\t\t}\n\t\t\tgen_gbt_work(pool, work);\n\t\t\tapplog(LOG_DEBUG, \"Generated GBT work\");\n\t\t\tstage_work(work);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (clone_available()) {\n\t\t\tapplog(LOG_DEBUG, \"Cloned getwork work\");\n\t\t\tfree_work(work);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (opt_benchmark) {\n\t\t\tget_benchmark_work(work);\n\t\t\tapplog(LOG_DEBUG, \"Generated benchmark work\");\n\t\t\tstage_work(work);\n\t\t\tcontinue;\n\t\t}\n\n\t\twork->pool = pool;\n\t\tce = pop_curl_entry(pool);\n\t\t/* obtain new work from bitcoin via JSON-RPC */\n\t\tif (!get_upstream_work(work, ce->curl)) {\n\t\t\tapplog(LOG_DEBUG, \"Pool %d json_rpc_call failed on get work, retrying in 5s\", pool->pool_no);\n\t\t\t/* Make sure the pool just hasn't stopped serving\n\t\t\t * requests but is up as we'll keep hammering it */\n\t\t\tif (++pool->seq_getfails > mining_threads + opt_queue)\n\t\t\t\tpool_died(pool);\n\t\t\tnmsleep(5000);\n\t\t\tpush_curl_entry(ce, pool);\n\t\t\tpool = select_pool(!opt_fail_only);\n\t\t\tgoto retry;\n\t\t}\n\t\tif (ts >= max_staged)\n\t\t\tpool_tclear(pool, &pool->lagging);\n\t\tif (pool_tclear(pool, &pool->idle))\n\t\t\tpool_resus(pool);\n\n\t\tapplog(LOG_DEBUG, \"Generated getwork work\");\n\t\tstage_work(work);\n\t\tpush_curl_entry(ce, pool);\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "experimental/Ztex-1-15y/cgminer-3.1.1/driver-icarus.c",
    "content": "/*\n * Copyright 2012 Luke Dashjr\n * Copyright 2012 Xiangfu <xiangfu@openmobilefree.com>\n * Copyright 2012 Andrew Smith\n *\n * This program is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License as published by the Free\n * Software Foundation; either version 3 of the License, or (at your option)\n * any later version.  See COPYING for more details.\n */\n\n/*\n * Those code should be works fine with V2 and V3 bitstream of Icarus.\n * Operation:\n *   No detection implement.\n *   Input: 64B = 32B midstate + 20B fill bytes + last 12 bytes of block head.\n *   Return: send back 32bits immediately when Icarus found a valid nonce.\n *           no query protocol implemented here, if no data send back in ~11.3\n *           seconds (full cover time on 32bit nonce range by 380MH/s speed)\n *           just send another work.\n * Notice:\n *   1. Icarus will start calculate when you push a work to them, even they\n *      are busy.\n *   2. The 2 FPGAs on Icarus will distribute the job, one will calculate the\n *      0 ~ 7FFFFFFF, another one will cover the 80000000 ~ FFFFFFFF.\n *   3. It's possible for 2 FPGAs both find valid nonce in the meantime, the 2\n *      valid nonce will all be send back.\n *   4. Icarus will stop work when: a valid nonce has been found or 32 bits\n *      nonce range is completely calculated.\n */\n\n//#define LANCELOT84\t\t// KRAMBLE Lancelot 84byte protocol, comment out for cainsmore CM1\n \n#include \"config.h\"\n#include \"miner.h\"\n\n#include <limits.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <dirent.h>\n#include <unistd.h>\n#ifndef WIN32\n  #include <termios.h>\n  #include <sys/stat.h>\n  #include <fcntl.h>\n  #ifndef O_CLOEXEC\n    #define O_CLOEXEC 0\n  #endif\n#else\n  #include <windows.h>\n  #include <io.h>\n#endif\n\n#include \"elist.h\"\n#include \"fpgautils.h\"\n// #include \"util.h\"\t// kramble for bin2hex() - already in miner.h\n\n// The serial I/O speed - Linux uses a define 'B115200' in bits/termios.h\n#define ICARUS_IO_SPEED 115200\n\n// The size of a successful nonce read\n#define ICARUS_READ_SIZE 4\n\n// Ensure the sizes are correct for the Serial read\n#if (ICARUS_READ_SIZE != 4)\n#error ICARUS_READ_SIZE must be 4\n#endif\n#define ASSERT1(condition) __maybe_unused static char sizeof_uint32_t_must_be_4[(condition)?1:-1]\nASSERT1(sizeof(uint32_t) == 4);\n\n#define ICARUS_READ_TIME(baud) ((double)ICARUS_READ_SIZE * (double)8.0 / (double)(baud))\n\n// Fraction of a second, USB timeout is measured in\n// i.e. 10 means 1/10 of a second\n#define TIME_FACTOR 10\n// It's 10 per second, thus value = 10/TIME_FACTOR =\n#define ICARUS_READ_FAULT_DECISECONDS 1\n\n// In timing mode: Default starting value until an estimate can be obtained\n// 5 seconds allows for up to a ~840MH/s device\n#define ICARUS_READ_COUNT_TIMING\t(5 * TIME_FACTOR)\n\n// For a standard Icarus REV3 (to 5 places)\n// Since this rounds up a the last digit - it is a slight overestimate\n// Thus the hash rate will be a VERY slight underestimate\n// (by a lot less than the displayed accuracy)\n// #define ICARUS_REV3_HASH_TIME 0.0000000026316\t\t// Original bitcoin timing\n// #define ICARUS_REV3_HASH_TIME 0.0001724645376\t\t// KRAMBLE for litecoin initially scale by 65536 (2^16)\n#define ICARUS_REV3_HASH_TIME 0.0006898581504\t\t\t// KRAMBLE scale by arbirary factor of 4 to make hashrate look about right\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// ... except its still wrong, but at least its kH/s rather than MH/s now.\n#define NANOSEC 1000000000.0\n\n// Icarus Rev3 doesn't send a completion message when it finishes\n// the full nonce range, so to avoid being idle we must abort the\n// work (by starting a new work) shortly before it finishes\n//\n// Thus we need to estimate 2 things:\n//\t1) How many hashes were done if the work was aborted\n//\t2) How high can the timeout be before the Icarus is idle,\n//\t\tto minimise the number of work started\n//\tWe set 2) to 'the calculated estimate' - 1\n//\tto ensure the estimate ends before idle\n//\n// The simple calculation used is:\n//\tTn = Total time in seconds to calculate n hashes\n//\tHs = seconds per hash\n//\tXn = number of hashes\n//\tW  = code overhead per work\n//\n// Rough but reasonable estimate:\n//\tTn = Hs * Xn + W\t(of the form y = mx + b)\n//\n// Thus:\n//\tLine of best fit (using least squares)\n//\n//\tHs = (n*Sum(XiTi)-Sum(Xi)*Sum(Ti))/(n*Sum(Xi^2)-Sum(Xi)^2)\n//\tW = Sum(Ti)/n - (Hs*Sum(Xi))/n\n//\n// N.B. W is less when aborting work since we aren't waiting for the reply\n//\tto be transferred back (ICARUS_READ_TIME)\n//\tCalculating the hashes aborted at n seconds is thus just n/Hs\n//\t(though this is still a slight overestimate due to code delays)\n//\n\n// Both below must be exceeded to complete a set of data\n// Minimum how long after the first, the last data point must be\n#define HISTORY_SEC 60\n// Minimum how many points a single ICARUS_HISTORY should have\n#define MIN_DATA_COUNT 5\n// The value above used is doubled each history until it exceeds:\n#define MAX_MIN_DATA_COUNT 100\n\nstatic struct timeval history_sec = { HISTORY_SEC, 0 };\n\n// Store the last INFO_HISTORY data sets\n// [0] = current data, not yet ready to be included as an estimate\n// Each new data set throws the last old set off the end thus\n// keeping a ongoing average of recent data\n#define INFO_HISTORY 10\n\nstruct ICARUS_HISTORY {\n\tstruct timeval finish;\n\tdouble sumXiTi;\n\tdouble sumXi;\n\tdouble sumTi;\n\tdouble sumXi2;\n\tuint32_t values;\n\tuint32_t hash_count_min;\n\tuint32_t hash_count_max;\n};\n\nenum timing_mode { MODE_DEFAULT, MODE_SHORT, MODE_LONG, MODE_VALUE };\n\nstatic const char *MODE_DEFAULT_STR = \"default\";\nstatic const char *MODE_SHORT_STR = \"short\";\nstatic const char *MODE_LONG_STR = \"long\";\nstatic const char *MODE_VALUE_STR = \"value\";\nstatic const char *MODE_UNKNOWN_STR = \"unknown\";\n\nstruct ICARUS_INFO {\n\t// time to calculate the golden_ob\n\tuint64_t golden_hashes;\n\tstruct timeval golden_tv;\n\n\tstruct ICARUS_HISTORY history[INFO_HISTORY+1];\n\tuint32_t min_data_count;\n\n\t// seconds per Hash\n\tdouble Hs;\n\tint read_count;\n\n\tenum timing_mode timing_mode;\n\tbool do_icarus_timing;\n\n\tdouble fullnonce;\n\tint count;\n\tdouble W;\n\tuint32_t values;\n\tuint64_t hash_count_range;\n\n\t// Determine the cost of history processing\n\t// (which will only affect W)\n\tuint64_t history_count;\n\tstruct timeval history_time;\n\n\t// icarus-options\n\tint baud;\n\tint work_division;\n\tint fpga_count;\n\tuint32_t nonce_mask;\n};\n\n#define END_CONDITION 0x0000ffff\n\n// One for each possible device\nstatic struct ICARUS_INFO **icarus_info;\n\n// Looking for options in --icarus-timing and --icarus-options:\n//\n// Code increments this each time we start to look at a device\n// However, this means that if other devices are checked by\n// the Icarus code (e.g. BFL) they will count in the option offset\n//\n// This, however, is deterministic so that's OK\n//\n// If we were to increment after successfully finding an Icarus\n// that would be random since an Icarus may fail and thus we'd\n// not be able to predict the option order\n//\n// This also assumes that serial_detect() checks them sequentially\n// and in the order specified on the command line\n//\nstatic int option_offset = -1;\nstatic int clock_offset = -1;\t\t// KRAMBLE\n\nstruct device_drv icarus_drv;\n\nstatic void rev(unsigned char *s, size_t l)\n{\n\tsize_t i, j;\n\tunsigned char t;\n\n\tfor (i = 0, j = l - 1; i < j; i++, j--) {\n\t\tt = s[i];\n\t\ts[i] = s[j];\n\t\ts[j] = t;\n\t}\n}\n\n#define icarus_open2(devpath, baud, purge)  serial_open(devpath, baud, ICARUS_READ_FAULT_DECISECONDS, purge)\n#define icarus_open(devpath, baud)  icarus_open2(devpath, baud, false)\n\n#define ICA_GETS_ERROR -1\n#define ICA_GETS_OK 0\n#define ICA_GETS_RESTART 1\n#define ICA_GETS_TIMEOUT 2\n\nstatic int icarus_gets(unsigned char *buf, int fd, struct timeval *tv_finish, struct thr_info *thr, int read_count)\n{\n\tssize_t ret = 0;\n\tint rc = 0;\n\tint read_amount = ICARUS_READ_SIZE;\n\tbool first = true;\n\n\t// Read reply 1 byte at a time to get earliest tv_finish\n\twhile (true) {\n\t\tret = read(fd, buf, 1);\n\t\tif (ret < 0)\n\t\t\treturn ICA_GETS_ERROR;\n\n\t\tif (first)\n\t\t\tcgtime(tv_finish);\n\n\t\tif (ret >= read_amount)\n\t\t\treturn ICA_GETS_OK;\n\n\t\tif (ret > 0) {\n\t\t\tbuf += ret;\n\t\t\tread_amount -= ret;\n\t\t\tfirst = false;\n\t\t\tcontinue;\n\t\t}\n\t\t\t\n\t\trc++;\n\t\tif (rc >= read_count) {\n\t\t\tif (opt_debug) {\n\t\t\t\tapplog(LOG_DEBUG,\n\t\t\t\t\t\"Icarus Read: No data in %.2f seconds\",\n\t\t\t\t\t(float)rc/(float)TIME_FACTOR);\n\t\t\t}\n\t\t\treturn ICA_GETS_TIMEOUT;\n\t\t}\n\n\t\tif (thr && thr->work_restart) {\n\t\t\tif (opt_debug) {\n\t\t\t\tapplog(LOG_DEBUG,\n\t\t\t\t\t\"Icarus Read: Work restart at %.2f seconds\",\n\t\t\t\t\t(float)(rc)/(float)TIME_FACTOR);\n\t\t\t}\n\t\t\treturn ICA_GETS_RESTART;\n\t\t}\n\t}\n}\n\nstatic int icarus_write(int fd, const void *buf, size_t bufLen)\n{\n\tsize_t ret;\n\n#if 0\n\tchar *hexstr;\n\thexstr = bin2hex(buf, bufLen);\n\tapplog(LOG_WARNING, \"icarus_write %s\", hexstr);\n\tfree(hexstr);\n#endif\n\n\tret = write(fd, buf, bufLen);\n\tif (unlikely(ret != bufLen))\n\t\treturn 1;\n\n\treturn 0;\n}\n\n// From BFGMiner (for clock speed) ...\nstatic bool cairnsmore_send_cmd(int fd, uint8_t cmd, uint8_t data, bool probe)\n{\n\t// Use this version for v03 onwards of the verilog\n\tint numbytes = 76;\t\t\t\t// KRAMBLE 76 byte protocol\n\n\t/* WORKS but we don't need some of the values ...\n\tunsigned char pkt[76] =\n\t\t\"bfg0\" \"\\xff\\xff\\xff\\xff\" \"\\xb5\\0\\0\\0\"\t\t\t\t\t\t\t\t// FFFFFFFF timestamp in data3 (12 bytes total)\n\t\t\"vdi\\xb7\"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// Command bytes at MSB of data2 (32 bytes total)\n\t\t\"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n\t\t\"bfg0\" \"\\xff\\xff\\xff\\xff\" \"\\xb5\\0\\0\\0\"\n\t\t\"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\";\t// 32 0's for data1 (midstate in bitcoin)\n\t*/\n\n\t// Seems to be OK ...\n\tunsigned char pkt[76] =\n\t\t\"\\0\\0\\0\\0\" \"\\xff\\xff\\xff\\xff\" \"\\0\\0\\0\\0\"\t\t\t\t\t\t\t// FFFFFFFF timestamp in data3 (12 bytes total)\n\t\t\"vdi\\xb7\"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// Command bytes at MSB of data2 (4 bytes)\n\t\t\"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\t\t\t// Remainder of data2 (28 bytes)\n\t\t\"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\";\t// 32 0's for data1 (midstate in bitcoin)\n\n\t// if (unlikely(probe))\n\t//\tpkt[61] = '\\x01';\t// KRAMBLE not implemented in verilog, and its relocated in the pkt anyway (but where to?)\n\tpkt[12] = 0xda ^ cmd ^ data;\n\tpkt[13] = data;\n\tpkt[14] = cmd;\n\t// pkt[15] = 0xb7;\t\t// cmd_prefix (included in string initializer above)\n\treturn write(fd, pkt, numbytes) == numbytes;\n}\n\n#if 0\nstatic bool V01_cairnsmore_send_cmd(int fd, uint8_t cmd, uint8_t data, bool probe)\n{\n\t// Use this version with v01 and v02 of the verilog\n\t// int numbytes = 80;\t\t\t// KRAMBLE 80 byte protocol\n\tint numbytes = 76;\t\t\t\t// KRAMBLE 76 byte protocol\n\tunsigned char pkt[80] =\n\t\t\"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n\t\t\"vdi\\xb7\"\n\t\t\"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n\t\t\"bfg0\" \"\\xff\\xff\\xff\\xff\" \"\\xb5\\0\\0\\0\";\t// KRAMBLE Automatically padded with 0's so should work fine\n\tif (unlikely(probe))\n\t\tpkt[61] = '\\x01';\n\tpkt[32] = 0xda ^ cmd ^ data;\n\tpkt[33] = data;\n\tpkt[34] = cmd;\n\t\n\t// KRAMBLE OOPS, I have data1 and data2 backwards in the verilog v01/v02, so workaround ...\n\tunsigned char pkt2[80] = { 0 };\t// Init to 0\n\tmemcpy (pkt2+12, pkt+32, 32);\n\treturn write(fd, pkt2, numbytes) == numbytes;\n}\n#endif\n// End BFGMiner\n\n#define icarus_close(fd) close(fd)\n\nstatic void do_icarus_close(struct thr_info *thr)\n{\n\tstruct cgpu_info *icarus = thr->cgpu;\n\ticarus_close(icarus->device_fd);\n\ticarus->device_fd = -1;\n}\n\nstatic const char *timing_mode_str(enum timing_mode timing_mode)\n{\n\tswitch(timing_mode) {\n\tcase MODE_DEFAULT:\n\t\treturn MODE_DEFAULT_STR;\n\tcase MODE_SHORT:\n\t\treturn MODE_SHORT_STR;\n\tcase MODE_LONG:\n\t\treturn MODE_LONG_STR;\n\tcase MODE_VALUE:\n\t\treturn MODE_VALUE_STR;\n\tdefault:\n\t\treturn MODE_UNKNOWN_STR;\n\t}\n}\n\nstatic void set_timing_mode(int this_option_offset, struct cgpu_info *icarus)\n{\n\tstruct ICARUS_INFO *info = icarus_info[icarus->device_id];\n\tdouble Hs;\n\tchar buf[BUFSIZ+1];\n\tchar *ptr, *comma, *eq;\n\tsize_t max;\n\tint i;\n\n\tif (opt_icarus_timing == NULL)\n\t\tbuf[0] = '\\0';\n\telse {\n\t\tptr = opt_icarus_timing;\n\t\tfor (i = 0; i < this_option_offset; i++) {\n\t\t\tcomma = strchr(ptr, ',');\n\t\t\tif (comma == NULL)\n\t\t\t\tbreak;\n\t\t\tptr = comma + 1;\n\t\t}\n\n\t\tcomma = strchr(ptr, ',');\n\t\tif (comma == NULL)\n\t\t\tmax = strlen(ptr);\n\t\telse\n\t\t\tmax = comma - ptr;\n\n\t\tif (max > BUFSIZ)\n\t\t\tmax = BUFSIZ;\n\t\tstrncpy(buf, ptr, max);\n\t\tbuf[max] = '\\0';\n\t}\n\n\tinfo->Hs = 0;\n\tinfo->read_count = 0;\n\n\tif (strcasecmp(buf, MODE_SHORT_STR) == 0) {\n\t\tinfo->Hs = ICARUS_REV3_HASH_TIME;\n\t\tinfo->read_count = ICARUS_READ_COUNT_TIMING;\n\n\t\tinfo->timing_mode = MODE_SHORT;\n\t\tinfo->do_icarus_timing = true;\n\t} else if (strcasecmp(buf, MODE_LONG_STR) == 0) {\n\t\tinfo->Hs = ICARUS_REV3_HASH_TIME;\n\t\tinfo->read_count = ICARUS_READ_COUNT_TIMING;\n\n\t\tinfo->timing_mode = MODE_LONG;\n\t\tinfo->do_icarus_timing = true;\n\t} else if ((Hs = atof(buf)) != 0) {\n\t\tinfo->Hs = Hs / NANOSEC;\n\t\tinfo->fullnonce = info->Hs * (((double)0xffffffff) + 1);\n\n\t\tif ((eq = strchr(buf, '=')) != NULL)\n\t\t\tinfo->read_count = atoi(eq+1);\n\n\t\tif (info->read_count < 1)\n\t\t\tinfo->read_count = (int)(info->fullnonce * TIME_FACTOR) - 1;\n\n\t\tif (unlikely(info->read_count < 1))\n\t\t\tinfo->read_count = 1;\n\n\t\tinfo->timing_mode = MODE_VALUE;\n\t\tinfo->do_icarus_timing = false;\n\t} else {\n\t\t// Anything else in buf just uses DEFAULT mode\n\n\t\tinfo->Hs = ICARUS_REV3_HASH_TIME;\n\t\tinfo->fullnonce = info->Hs * (((double)0xffffffff) + 1);\n\n\t\tif ((eq = strchr(buf, '=')) != NULL)\n\t\t\tinfo->read_count = atoi(eq+1);\n\n\t\tif (info->read_count < 1)\n\t\t\tinfo->read_count = (int)(info->fullnonce * TIME_FACTOR) - 1;\n\n\t\tinfo->timing_mode = MODE_DEFAULT;\n\t\tinfo->do_icarus_timing = false;\n\t}\n\n\tinfo->min_data_count = MIN_DATA_COUNT;\n\n\tapplog(LOG_DEBUG, \"Icarus: Init: %d mode=%s read_count=%d Hs=%e\",\n\t\ticarus->device_id, timing_mode_str(info->timing_mode), info->read_count, info->Hs);\n}\n\nstatic uint32_t mask(int work_division)\n{\n\tchar err_buf[BUFSIZ+1];\n\tuint32_t nonce_mask = 0x7fffffff;\n\n\t// yes we can calculate these, but this way it's easy to see what they are\n\tswitch (work_division) {\n\tcase 1:\n\t\tnonce_mask = 0xffffffff;\n\t\tbreak;\n\tcase 2:\n\t\tnonce_mask = 0x7fffffff;\n\t\tbreak;\n\tcase 4:\n\t\tnonce_mask = 0x3fffffff;\n\t\tbreak;\n\tcase 8:\n\t\tnonce_mask = 0x1fffffff;\n\t\tbreak;\n\tdefault:\n\t\tsprintf(err_buf, \"Invalid2 icarus-options for work_division (%d) must be 1, 2, 4 or 8\", work_division);\n\t\tquit(1, err_buf);\n\t}\n\n\treturn nonce_mask;\n}\n\nstatic void get_options(int this_option_offset, int *baud, int *work_division, int *fpga_count)\n{\n\tchar err_buf[BUFSIZ+1];\n\tchar buf[BUFSIZ+1];\n\tchar *ptr, *comma, *colon, *colon2;\n\tsize_t max;\n\tint i, tmp;\n\n\tif (opt_icarus_options == NULL)\n\t\tbuf[0] = '\\0';\n\telse {\n\t\tptr = opt_icarus_options;\n\t\tfor (i = 0; i < this_option_offset; i++) {\n\t\t\tcomma = strchr(ptr, ',');\n\t\t\tif (comma == NULL)\n\t\t\t\tbreak;\n\t\t\tptr = comma + 1;\n\t\t}\n\n\t\tcomma = strchr(ptr, ',');\n\t\tif (comma == NULL)\n\t\t\tmax = strlen(ptr);\n\t\telse\n\t\t\tmax = comma - ptr;\n\n\t\tif (max > BUFSIZ)\n\t\t\tmax = BUFSIZ;\n\t\tstrncpy(buf, ptr, max);\n\t\tbuf[max] = '\\0';\n\t}\n\n\t*baud = ICARUS_IO_SPEED;\n\t*work_division = 2;\n\t*fpga_count = 2;\n\n\tif (*buf) {\n\t\tcolon = strchr(buf, ':');\n\t\tif (colon)\n\t\t\t*(colon++) = '\\0';\n\n\t\tif (*buf) {\n\t\t\ttmp = atoi(buf);\n\t\t\tswitch (tmp) {\n\t\t\tcase 115200:\n\t\t\t\t*baud = 115200;\n\t\t\t\tbreak;\n\t\t\tcase 57600:\n\t\t\t\t*baud = 57600;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tsprintf(err_buf, \"Invalid icarus-options for baud (%s) must be 115200 or 57600\", buf);\n\t\t\t\tquit(1, err_buf);\n\t\t\t}\n\t\t}\n\n\t\tif (colon && *colon) {\n\t\t\tcolon2 = strchr(colon, ':');\n\t\t\tif (colon2)\n\t\t\t\t*(colon2++) = '\\0';\n\n\t\t\tif (*colon) {\n\t\t\t\ttmp = atoi(colon);\n\t\t\t\tif (tmp == 1 || tmp == 2 || tmp == 4 || tmp == 8) {\n\t\t\t\t\t*work_division = tmp;\n\t\t\t\t\t*fpga_count = tmp;\t// default to the same\n\t\t\t\t} else {\n\t\t\t\t\tsprintf(err_buf, \"Invalid icarus-options for work_division (%s) must be 1, 2, 4 or 8\", colon);\n\t\t\t\t\tquit(1, err_buf);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (colon2 && *colon2) {\n\t\t\t\ttmp = atoi(colon2);\n\t\t\t\tif (tmp > 0 && tmp <= *work_division)\n\t\t\t\t\t*fpga_count = tmp;\n\t\t\t\telse {\n\t\t\t\t\tsprintf(err_buf, \"Invalid icarus-options for fpga_count (%s) must be >0 and <=work_division (%d)\", colon2, *work_division);\n\t\t\t\t\tquit(1, err_buf);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic void get_clocks(int this_option_offset, int *cainsmore_clock)\n{\n\tchar err_buf[BUFSIZ+1];\n\tchar buf[BUFSIZ+1];\n\tchar *ptr, *comma;\n\tsize_t max;\n\tint i, tmp;\n\n\tif (opt_cainsmore_clock == NULL)\n\t\tbuf[0] = '\\0';\n\telse {\n\t\tptr = opt_cainsmore_clock;\n\t\tfor (i = 0; i < this_option_offset; i++) {\n\t\t\tcomma = strchr(ptr, ',');\n\t\t\tif (comma == NULL)\n\t\t\t\tbreak;\n\t\t\tptr = comma + 1;\n\t\t}\n\n\t\tcomma = strchr(ptr, ',');\n\t\tif (comma == NULL)\n\t\t\tmax = strlen(ptr);\n\t\telse\n\t\t\tmax = comma - ptr;\n\n\t\tif (max > BUFSIZ)\n\t\t\tmax = BUFSIZ;\n\t\tstrncpy(buf, ptr, max);\n\t\tbuf[max] = '\\0';\n\t}\n\n\tif (*buf) {\n\t\ttmp = atoi(buf);\n\n\t\tif (tmp >= 50 && tmp <= 300)\t\t\t// 120 * 2.5 MHz (DCM_MULTIPLIER_CAP=120 cf 88 in original)\n\t\t\t\t*cainsmore_clock = tmp * 2 / 5;\t// NB 2.5Mhz units\n\t\t\telse {\n\t\t\t\tsprintf(err_buf, \"Invalid cainsmore-clock must be between 100 and 300\", buf);\n\t\t\t\tquit(1, err_buf);\n\t\t\t}\n\t}\n}\n\nstatic bool icarus_detect_one(const char *devpath)\n{\n\tint this_option_offset = ++option_offset;\n\tint this_clock_offset = ++clock_offset;\n\n\tstruct ICARUS_INFO *info;\n\tstruct timeval tv_start, tv_finish;\n\tint fd;\n\n#ifdef LANCELOT84\n\tint numbytes = 84;\t\t\t\t// KRAMBLE 84 byte protocol\n#else\n\tint numbytes = 76;\t\t\t\t// KRAMBLE 76 byte protocol\n#endif\n\n/*\t\t\n\tJust a random diff=2 share ...\n\tN.B. golden_ob MUST take less time to calculate than the timeout set in icarus_open()\n\t12192c1b70c094521b40cc61cdb836325924f2c97d9427fbd55091040ed1e7b30de7dcff8dde0ba8979f8506202b8e8abb00ad2e9fa81441d8be667893ce129737c9908d6983412401000000\n\n\tShare found 00000047\n */\n\n#ifdef LANCELOT84\n\tconst char golden_ob[] =\n\t\t\"00007fff00000000\"\t\t\t\t\t// Prefix with diff=2 target (00007fff) and initial nonce 00000000\n\t\t\"12192c1b70c094521b40cc61cdb83632\"\n\t\t\"5924f2c97d9427fbd55091040ed1e7b3\"\n\t\t\"0de7dcff8dde0ba8979f8506202b8e8a\"\n\t\t\"bb00ad2e9fa81441d8be667893ce1297\"\n\t\t\"37c9908d6983412401000000\";\n#else\n\tconst char golden_ob[] =\n\t\t\"12192c1b70c094521b40cc61cdb83632\"\n\t\t\"5924f2c97d9427fbd55091040ed1e7b3\"\n\t\t\"0de7dcff8dde0ba8979f8506202b8e8a\"\n\t\t\"bb00ad2e9fa81441d8be667893ce1297\"\n\t\t\"37c9908d6983412401000000\";\n#endif\n\t\n\tconst char golden_nonce[] = \"00000047\";\n\tconst uint32_t golden_nonce_val = 0x00000047;\n\n\tunsigned char ob_bin[84], nonce_bin[ICARUS_READ_SIZE];\n\tchar *nonce_hex;\n\n\tint baud, work_division, fpga_count;\n\n\tget_options(this_option_offset, &baud, &work_division, &fpga_count);\n\n\t// KRAMBLE Units 2.5MHz Min 20, Max 88\n\t// NB Divided by 4 internally so 200MHz gives 50MHz pbkdf/salsa clock\n\n#ifdef LANCELOT84\n\tint cainsmore_clock_speed = 45;\t\t\t// Actual MHz (max is around 50MHz for dualcore bitstream)\n#else\n\tint cainsmore_clock_speed = 60;\t\t\t// 150MHz default\n#endif\n\t\n\tget_clocks(this_option_offset, &cainsmore_clock_speed);\n\t// applog(LOG_INFO, \"cainsmore set clock: %dMHz\", cainsmore_clock_speed * 5 / 2);\t// Works, but crashes !!\n\n\tapplog(LOG_DEBUG, \"Icarus Detect: Attempting to open %s\", devpath);\n\n\tfd = icarus_open2(devpath, baud, true);\n\tif (unlikely(fd == -1)) {\n\t\tapplog(LOG_ERR, \"Icarus Detect: Failed to open %s\", devpath);\n\t\treturn false;\n\t}\n\n\thex2bin(ob_bin, golden_ob, numbytes);\t// KRAMBLE\n\ticarus_write(fd, ob_bin, numbytes);\n\tcgtime(&tv_start);\n\n\tmemset(nonce_bin, 0, sizeof(nonce_bin));\n\ticarus_gets(nonce_bin, fd, &tv_finish, NULL, 1);\n\n#ifndef LANCELOT84\n#endif\n\n#ifdef LANCELOT84\n\t// Send packet to set LANCELOT clock speed - expects units of MHz, but cainsmore_clock_speed\n\t// has a reasonable range (command line parameter / 2.5) so use this directly for now (with tweaked\n\t// intial value above)\n\tob_bin[0] = cainsmore_clock_speed;\n\tob_bin[1] = 255 - cainsmore_clock_speed;\t// ones complement\n\ticarus_write(fd, ob_bin, numbytes);\n#else\t\n\tint cainsmore_ret = cairnsmore_send_cmd(fd, 0, cainsmore_clock_speed, false);\n\t// applog(LOG_ERR, \"cainsmore set clock: %s\", cainsmore_ret ? \"true\" : \"false\");\t// Works, but crashes !!\n#endif\n\n\ticarus_close(fd);\t// KRAMBLE MOVED below (2 places)\n\n\tnonce_hex = bin2hex(nonce_bin, sizeof(nonce_bin));\n\tif (strncmp(nonce_hex, golden_nonce, 8)) {\n\t\tapplog(LOG_ERR,\n\t\t\t\"Icarus Detect: \"\n\t\t\t\"Test failed at %s: get %s, should: %s\",\n\t\t\tdevpath, nonce_hex, golden_nonce);\n#if 1\t// KRAMBLE Set 0 to DISABLE TEST\n\t\tfree(nonce_hex);\n\t\treturn false;\n#endif\n\t}\n\tapplog(LOG_DEBUG,\n\t\t\"Icarus Detect: \"\n\t\t\"Test succeeded at %s: got %s\",\n\t\t\tdevpath, nonce_hex);\n\tfree(nonce_hex);\n\n\t/* We have a real Icarus! */\n\tstruct cgpu_info *icarus;\n\ticarus = calloc(1, sizeof(struct cgpu_info));\n\ticarus->drv = &icarus_drv;\n\ticarus->device_path = strdup(devpath);\n\ticarus->device_fd = -1;\n\ticarus->threads = 1;\n\tadd_cgpu(icarus);\n\ticarus_info = realloc(icarus_info, sizeof(struct ICARUS_INFO *) * (total_devices + 1));\n\n\tapplog(LOG_INFO, \"Found Icarus at %s, mark as %d\",\n\t\tdevpath, icarus->device_id);\n\n\tapplog(LOG_DEBUG, \"Icarus: Init: %d baud=%d work_division=%d fpga_count=%d\",\n\t\ticarus->device_id, baud, work_division, fpga_count);\n\n\t// Since we are adding a new device on the end it needs to always be allocated\n\ticarus_info[icarus->device_id] = (struct ICARUS_INFO *)malloc(sizeof(struct ICARUS_INFO));\n\tif (unlikely(!(icarus_info[icarus->device_id])))\n\t\tquit(1, \"Failed to malloc ICARUS_INFO\");\n\n\tinfo = icarus_info[icarus->device_id];\n\n\t// Initialise everything to zero for a new device\n\tmemset(info, 0, sizeof(struct ICARUS_INFO));\n\n\tinfo->baud = baud;\n\tinfo->work_division = work_division;\n\tinfo->fpga_count = fpga_count;\n\tinfo->nonce_mask = mask(work_division);\n\n\tinfo->golden_hashes = (golden_nonce_val & info->nonce_mask) * fpga_count;\n\ttimersub(&tv_finish, &tv_start, &(info->golden_tv));\n\n\tset_timing_mode(this_option_offset, icarus);\n\n\treturn true;\n}\n\nstatic void icarus_detect()\n{\n\tserial_detect(&icarus_drv, icarus_detect_one);\n}\n\nstatic bool icarus_prepare(struct thr_info *thr)\n{\n\tstruct cgpu_info *icarus = thr->cgpu;\n\n\tstruct timeval now;\n\n\ticarus->device_fd = -1;\n\n\tint fd = icarus_open(icarus->device_path, icarus_info[icarus->device_id]->baud);\n\tif (unlikely(-1 == fd)) {\n\t\tapplog(LOG_ERR, \"Failed to open Icarus on %s\",\n\t\t       icarus->device_path);\n\t\treturn false;\n\t}\n\n\ticarus->device_fd = fd;\n\n\tapplog(LOG_INFO, \"Opened Icarus on %s\", icarus->device_path);\n\tcgtime(&now);\n\tget_datestamp(icarus->init, &now);\n\n\treturn true;\n}\n\nstatic int64_t icarus_scanhash(struct thr_info *thr, struct work *work,\n\t\t\t\t__maybe_unused int64_t max_nonce)\n{\n\tstruct cgpu_info *icarus;\n\tint fd;\n\tint ret;\n\n\tstruct ICARUS_INFO *info;\n\n#ifdef LANCELOT84\n\tint numbytes = 84;\t\t\t\t// KRAMBLE 84 byte protocol\n#else\n\tint numbytes = 76;\t\t\t\t// KRAMBLE 76 byte protocol\n#endif\n\n\t// KRAMBLE work around BUG where same work is sent multiple times causing duplicate shares\n#define KRAMBLE_MAXICARUS 256\t\t\t\t// Ought to dynamically allocate this according to icarus->device_id\n\tstatic uint32_t kramble_submitted_nonce[KRAMBLE_MAXICARUS];\n\tstatic unsigned char kramble_prev_ob_bin[84*KRAMBLE_MAXICARUS];\n\t\n\t// KRAMBLE ob_bin[84] allows for either 76 or 84 byte protocol\n\tunsigned char ob_bin[84], nonce_bin[ICARUS_READ_SIZE];\n\tchar *ob_hex;\n\tuint32_t nonce;\n\tint64_t hash_count;\n\tstruct timeval tv_start, tv_finish, elapsed;\n\tstruct timeval tv_history_start, tv_history_finish;\n\tdouble Ti, Xi;\n\tint curr_hw_errors, i;\n\tbool was_hw_error;\n\n\tstruct ICARUS_HISTORY *history0, *history;\n\tint count;\n\tdouble Hs, W, fullnonce;\n\tint read_count;\n\tint64_t estimate_hashes;\n\tuint32_t values;\n\tint64_t hash_count_range;\n\n\telapsed.tv_sec = elapsed.tv_usec = 0;\n\n\ticarus = thr->cgpu;\n\tif (icarus->device_fd == -1)\n\t\tif (!icarus_prepare(thr)) {\n\t\t\tapplog(LOG_ERR, \"%s%i: Comms error\", icarus->drv->name, icarus->device_id);\n\t\t\tdev_error(icarus, REASON_DEV_COMMS_ERROR);\n\n\t\t\t// fail the device if the reopen attempt fails\n\t\t\treturn -1;\n\t\t}\n\n\tfd = icarus->device_fd;\n\n#ifdef LANCELOT84\n\tconst unsigned char noncetarg[] = \"\\0\\0\\0\\0\\xff\\x7f\\0\\0\";\t// initial nonce 00000000 and diff=2 target (00007fff)\n\tmemcpy(ob_bin, work->data, 76);\n\tmemcpy(ob_bin+76, noncetarg, 8);\n\trev(ob_bin, numbytes);\n#else\n\tmemcpy(ob_bin, work->data, numbytes);\n\trev(ob_bin, numbytes);\n#endif\n\n#ifndef WIN32\n\ttcflush(fd, TCOFLUSH);\n#endif\n\t\n\t// KRAMBLE work around BUG where same work is sent multiple times causing duplicate shares\n\tint kramble_id = icarus->device_id;\n\tif (kramble_id < 0)\n\t\tkramble_id = 0;\n\telse if (kramble_id >= KRAMBLE_MAXICARUS)\n\t\tkramble_id = KRAMBLE_MAXICARUS - 1;\t// Don't overflow (ought to abort or something)\n\n\tunsigned char *kramble_this_prev_ob_bin = kramble_prev_ob_bin + 84 * kramble_id;\n\tif (memcmp(kramble_this_prev_ob_bin, ob_bin, numbytes))\n\t{\t\n\t\tmemcpy(kramble_this_prev_ob_bin, ob_bin, numbytes);\n\t\tapplog(LOG_INFO, \"Icarus %d: SEND WORK\", icarus->device_id);\n\t\n\t\tret = icarus_write(fd, ob_bin, numbytes);\t// KRAMBLE\n\t\tif (ret) {\n\t\t\tdo_icarus_close(thr);\n\t\t\tapplog(LOG_ERR, \"%s%i: Comms error\", icarus->drv->name, icarus->device_id);\n\t\t\tdev_error(icarus, REASON_DEV_COMMS_ERROR);\n\t\t\treturn 0;\t/* This should never happen */\n\t\t}\n\t}\n\telse\n\t{\n\t\t// Just ignore else the fpga will reset nonce and may find the same share over and over again\n\t\tapplog(LOG_INFO, \"Icarus %d: DUPLICATE SEND WORK\", icarus->device_id);\n\t}\n\n\tcgtime(&tv_start);\n\n\tif (opt_debug) {\n\t\tob_hex = bin2hex(ob_bin, sizeof(ob_bin));\n\t\tapplog(LOG_DEBUG, \"Icarus %d sent: %s\",\n\t\t\ticarus->device_id, ob_hex);\n\t\tfree(ob_hex);\n\t}\n\n\t/* Icarus will return 4 bytes (ICARUS_READ_SIZE) nonces or nothing */\n\tmemset(nonce_bin, 0, sizeof(nonce_bin));\n\tinfo = icarus_info[icarus->device_id];\n\tret = icarus_gets(nonce_bin, fd, &tv_finish, thr, info->read_count);\n\tif (ret == ICA_GETS_ERROR) {\n\t\tdo_icarus_close(thr);\n\t\tapplog(LOG_ERR, \"%s%i: Comms error\", icarus->drv->name, icarus->device_id);\n\t\tdev_error(icarus, REASON_DEV_COMMS_ERROR);\n\t\treturn 0;\n\t}\n\n\twork->blk.nonce = 0xffffffff;\n\n\t// aborted before becoming idle, get new work\n\tif (ret == ICA_GETS_TIMEOUT || ret == ICA_GETS_RESTART) {\n\t\ttimersub(&tv_finish, &tv_start, &elapsed);\n\n\t\t// ONLY up to just when it aborted\n\t\t// We didn't read a reply so we don't subtract ICARUS_READ_TIME\n\t\testimate_hashes = ((double)(elapsed.tv_sec)\n\t\t\t\t\t+ ((double)(elapsed.tv_usec))/((double)1000000)) / info->Hs;\n\n\t\t// If some Serial-USB delay allowed the full nonce range to\n\t\t// complete it can't have done more than a full nonce\n\t\tif (unlikely(estimate_hashes > 0xffffffff))\n\t\t\testimate_hashes = 0xffffffff;\n\n\t\tif (opt_debug) {\n\t\t\tapplog(LOG_DEBUG, \"Icarus %d no nonce = 0x%08lX hashes (%ld.%06lds)\",\n\t\t\t\t\ticarus->device_id, (long unsigned int)estimate_hashes,\n\t\t\t\t\telapsed.tv_sec, elapsed.tv_usec);\n\t\t}\n\n\t\treturn estimate_hashes;\n\t}\n\n\tmemcpy((char *)&nonce, nonce_bin, sizeof(nonce_bin));\n\n#if !defined (__BIG_ENDIAN__) && !defined(MIPSEB)\n\tnonce = swab32(nonce);\n#endif\n\n\t// KRAMBLE copy the LOG_DEBUG from below as LOG_INFO (hash_count & elapsed are always zero) and reformat\n\t// to match the zted message (this is useful to show its working as accept rate is dismal when solo mining)\n\tapplog(LOG_INFO, \"Icarus %d: Share found %08x\", icarus->device_id, nonce);\n\n\tcurr_hw_errors = icarus->hw_errors;\n\n\t// KRAMBLE original workaround for BUG (superceeded by kramble_prev_ob_bin above)\n#if 1\n\tsubmit_nonce(thr, work, nonce); \t\t// ORIGINAL\n#else\n\t// Poor workaround as it rejects identical nonces which might actually be valid\n\tif (nonce != kramble_submitted_nonce[kramble_id])\n\t{\n\t\tapplog(LOG_WARNING, \"Icarus %d: SUBMITTED\", icarus->device_id);\n\t\tsubmit_nonce(thr, work, nonce);\n\t}\n\telse\n\t\tapplog(LOG_WARNING, \"Icarus %d: WITHHELD\", icarus->device_id);\n\n\tkramble_submitted_nonce[kramble_id] = nonce;\n#endif\n\n\twas_hw_error = (curr_hw_errors > icarus->hw_errors);\n\n\t// Force a USB close/reopen on any hw error\n\tif (was_hw_error)\n\t\tdo_icarus_close(thr);\n\n\thash_count = (nonce & info->nonce_mask);\n\thash_count++;\n\thash_count *= info->fpga_count;\n\n\tif (opt_debug || info->do_icarus_timing)\n\t\ttimersub(&tv_finish, &tv_start, &elapsed);\n\n\tif (opt_debug) {\n\t\tapplog(LOG_DEBUG, \"Icarus %d nonce = 0x%08x = 0x%08lX hashes (%ld.%06lds)\",\n\t\t\t\ticarus->device_id, nonce, (long unsigned int)hash_count,\n\t\t\t\telapsed.tv_sec, elapsed.tv_usec);\n\t}\n\n\t// ignore possible end condition values ... and hw errors\n\tif (info->do_icarus_timing\n\t&&  !was_hw_error\n\t&&  ((nonce & info->nonce_mask) > END_CONDITION)\n\t&&  ((nonce & info->nonce_mask) < (info->nonce_mask & ~END_CONDITION))) {\n\t\tcgtime(&tv_history_start);\n\n\t\thistory0 = &(info->history[0]);\n\n\t\tif (history0->values == 0)\n\t\t\ttimeradd(&tv_start, &history_sec, &(history0->finish));\n\n\t\tTi = (double)(elapsed.tv_sec)\n\t\t\t+ ((double)(elapsed.tv_usec))/((double)1000000)\n\t\t\t- ((double)ICARUS_READ_TIME(info->baud));\n\t\tXi = (double)hash_count;\n\t\thistory0->sumXiTi += Xi * Ti;\n\t\thistory0->sumXi += Xi;\n\t\thistory0->sumTi += Ti;\n\t\thistory0->sumXi2 += Xi * Xi;\n\n\t\thistory0->values++;\n\n\t\tif (history0->hash_count_max < hash_count)\n\t\t\thistory0->hash_count_max = hash_count;\n\t\tif (history0->hash_count_min > hash_count || history0->hash_count_min == 0)\n\t\t\thistory0->hash_count_min = hash_count;\n\n\t\tif (history0->values >= info->min_data_count\n\t\t&&  timercmp(&tv_start, &(history0->finish), >)) {\n\t\t\tfor (i = INFO_HISTORY; i > 0; i--)\n\t\t\t\tmemcpy(&(info->history[i]),\n\t\t\t\t\t&(info->history[i-1]),\n\t\t\t\t\tsizeof(struct ICARUS_HISTORY));\n\n\t\t\t// Initialise history0 to zero for summary calculation\n\t\t\tmemset(history0, 0, sizeof(struct ICARUS_HISTORY));\n\n\t\t\t// We just completed a history data set\n\t\t\t// So now recalc read_count based on the whole history thus we will\n\t\t\t// initially get more accurate until it completes INFO_HISTORY\n\t\t\t// total data sets\n\t\t\tcount = 0;\n\t\t\tfor (i = 1 ; i <= INFO_HISTORY; i++) {\n\t\t\t\thistory = &(info->history[i]);\n\t\t\t\tif (history->values >= MIN_DATA_COUNT) {\n\t\t\t\t\tcount++;\n\n\t\t\t\t\thistory0->sumXiTi += history->sumXiTi;\n\t\t\t\t\thistory0->sumXi += history->sumXi;\n\t\t\t\t\thistory0->sumTi += history->sumTi;\n\t\t\t\t\thistory0->sumXi2 += history->sumXi2;\n\t\t\t\t\thistory0->values += history->values;\n\n\t\t\t\t\tif (history0->hash_count_max < history->hash_count_max)\n\t\t\t\t\t\thistory0->hash_count_max = history->hash_count_max;\n\t\t\t\t\tif (history0->hash_count_min > history->hash_count_min || history0->hash_count_min == 0)\n\t\t\t\t\t\thistory0->hash_count_min = history->hash_count_min;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// All history data\n\t\t\tHs = (history0->values*history0->sumXiTi - history0->sumXi*history0->sumTi)\n\t\t\t\t/ (history0->values*history0->sumXi2 - history0->sumXi*history0->sumXi);\n\t\t\tW = history0->sumTi/history0->values - Hs*history0->sumXi/history0->values;\n\t\t\thash_count_range = history0->hash_count_max - history0->hash_count_min;\n\t\t\tvalues = history0->values;\n\t\t\t\n\t\t\t// Initialise history0 to zero for next data set\n\t\t\tmemset(history0, 0, sizeof(struct ICARUS_HISTORY));\n\n\t\t\tfullnonce = W + Hs * (((double)0xffffffff) + 1);\n\t\t\tread_count = (int)(fullnonce * TIME_FACTOR) - 1;\n\n\t\t\tinfo->Hs = Hs;\n\t\t\tinfo->read_count = read_count;\n\n\t\t\tinfo->fullnonce = fullnonce;\n\t\t\tinfo->count = count;\n\t\t\tinfo->W = W;\n\t\t\tinfo->values = values;\n\t\t\tinfo->hash_count_range = hash_count_range;\n\n\t\t\tif (info->min_data_count < MAX_MIN_DATA_COUNT)\n\t\t\t\tinfo->min_data_count *= 2;\n\t\t\telse if (info->timing_mode == MODE_SHORT)\n\t\t\t\tinfo->do_icarus_timing = false;\n\n//\t\t\tapplog(LOG_WARNING, \"Icarus %d Re-estimate: read_count=%d fullnonce=%fs history count=%d Hs=%e W=%e values=%d hash range=0x%08lx min data count=%u\", icarus->device_id, read_count, fullnonce, count, Hs, W, values, hash_count_range, info->min_data_count);\n\t\t\tapplog(LOG_WARNING, \"Icarus %d Re-estimate: Hs=%e W=%e read_count=%d fullnonce=%.3fs\",\n\t\t\t\t\ticarus->device_id, Hs, W, read_count, fullnonce);\n\t\t}\n\t\tinfo->history_count++;\n\t\tcgtime(&tv_history_finish);\n\n\t\ttimersub(&tv_history_finish, &tv_history_start, &tv_history_finish);\n\t\ttimeradd(&tv_history_finish, &(info->history_time), &(info->history_time));\n\t}\n\n\treturn hash_count;\n}\n\nstatic struct api_data *icarus_api_stats(struct cgpu_info *cgpu)\n{\n\tstruct api_data *root = NULL;\n\tstruct ICARUS_INFO *info = icarus_info[cgpu->device_id];\n\n\t// Warning, access to these is not locked - but we don't really\n\t// care since hashing performance is way more important than\n\t// locking access to displaying API debug 'stats'\n\t// If locking becomes an issue for any of them, use copy_data=true also\n\troot = api_add_int(root, \"read_count\", &(info->read_count), false);\n\troot = api_add_double(root, \"fullnonce\", &(info->fullnonce), false);\n\troot = api_add_int(root, \"count\", &(info->count), false);\n\troot = api_add_hs(root, \"Hs\", &(info->Hs), false);\n\troot = api_add_double(root, \"W\", &(info->W), false);\n\troot = api_add_uint(root, \"total_values\", &(info->values), false);\n\troot = api_add_uint64(root, \"range\", &(info->hash_count_range), false);\n\troot = api_add_uint64(root, \"history_count\", &(info->history_count), false);\n\troot = api_add_timeval(root, \"history_time\", &(info->history_time), false);\n\troot = api_add_uint(root, \"min_data_count\", &(info->min_data_count), false);\n\troot = api_add_uint(root, \"timing_values\", &(info->history[0].values), false);\n\troot = api_add_const(root, \"timing_mode\", timing_mode_str(info->timing_mode), false);\n\troot = api_add_bool(root, \"is_timing\", &(info->do_icarus_timing), false);\n\troot = api_add_int(root, \"baud\", &(info->baud), false);\n\troot = api_add_int(root, \"work_division\", &(info->work_division), false);\n\troot = api_add_int(root, \"fpga_count\", &(info->fpga_count), false);\n\n\treturn root;\n}\n\nstatic void icarus_shutdown(struct thr_info *thr)\n{\n\tdo_icarus_close(thr);\n}\n\nstruct device_drv icarus_drv = {\n\t.drv_id = DRIVER_ICARUS,\n\t.dname = \"Icarus\",\n\t.name = \"ICA\",\n\t.drv_detect = icarus_detect,\n\t.get_api_stats = icarus_api_stats,\n\t.thread_prepare = icarus_prepare,\n\t.scanhash = icarus_scanhash,\n\t.thread_shutdown = icarus_shutdown,\n};\n"
  },
  {
    "path": "experimental/Ztex-1-15y/cgminer-3.1.1/driver-ztex.c",
    "content": "/**\n *   ztex.c - cgminer worker for Ztex 1.15x fpga board\n *\n *   Copyright (c) 2012 nelisky.btc@gmail.com\n *\n *   This work is based upon the Java SDK provided by ztex which is\n *   Copyright (C) 2009-2011 ZTEX GmbH.\n *   http://www.ztex.de\n *\n *   This work is based upon the icarus.c worker which is\n *   Copyright 2012 Luke Dashjr\n *   Copyright 2012 Xiangfu <xiangfu@openmobilefree.com>\n *\n *   This program is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License version 2 as\n *   published by the Free Software Foundation.\n *\n *   This program is distributed in the hope that it will be useful, but\n *   WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n *   General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program; if not, see http://www.gnu.org/licenses/.\n**/\n\n#include \"miner.h\"\n#include <unistd.h>\n#include <sha2.h>\n#include \"libztex.h\"\n#include \"util.h\"\n\n#define GOLDEN_BACKLOG 5\n\nstruct device_drv ztex_drv;\n\nstatic int option_offset = -1;\t\t// KRAMBLE used for ztex_clock option\n\n// Forward declarations\nstatic void ztex_disable(struct thr_info* thr);\nstatic bool ztex_prepare(struct thr_info *thr);\n\nstatic void ztex_selectFpga(struct libztex_device* ztex)\n{\n\tif (ztex->root->numberOfFpgas > 1) {\n\t\tif (ztex->root->selectedFpga != ztex->fpgaNum)\n\t\t\tmutex_lock(&ztex->root->mutex);\n\t\tlibztex_selectFpga(ztex);\n\t}\n}\n\nstatic void ztex_releaseFpga(struct libztex_device* ztex)\n{\n\tif (ztex->root->numberOfFpgas > 1) {\n\t\tztex->root->selectedFpga = -1;\n\t\tmutex_unlock(&ztex->root->mutex);\n\t}\n}\n\nstatic void ztex_detect(void)\n{\n\tint cnt;\n\tint i,j;\n\tint fpgacount;\n\tstruct libztex_dev_list **ztex_devices;\n\tstruct libztex_device *ztex_slave;\n\tstruct cgpu_info *ztex;\n\n\tcnt = libztex_scanDevices(&ztex_devices);\n\tif (cnt > 0)\n\t\tapplog(LOG_WARNING, \"Found %d ztex board%s\", cnt, cnt > 1 ? \"s\" : \"\");\n\n\tfor (i = 0; i < cnt; i++) {\n\t\tztex = calloc(1, sizeof(struct cgpu_info));\n\t\tztex->drv = &ztex_drv;\n\t\tztex->device_ztex = ztex_devices[i]->dev;\n\t\tztex->threads = 1;\n\t\tztex->device_ztex->fpgaNum = 0;\n\t\tztex->device_ztex->root = ztex->device_ztex;\n\t\tadd_cgpu(ztex);\n\n\t\tfpgacount = libztex_numberOfFpgas(ztex->device_ztex);\n\n\t\tif (fpgacount > 1)\n\t\t\tpthread_mutex_init(&ztex->device_ztex->mutex, NULL);\n\n\t\tfor (j = 1; j < fpgacount; j++) {\n\t\t\tztex = calloc(1, sizeof(struct cgpu_info));\n\t\t\tztex->drv = &ztex_drv;\n\t\t\tztex_slave = calloc(1, sizeof(struct libztex_device));\n\t\t\tmemcpy(ztex_slave, ztex_devices[i]->dev, sizeof(struct libztex_device));\n\t\t\tztex->device_ztex = ztex_slave;\n\t\t\tztex->threads = 1;\n\t\t\tztex_slave->fpgaNum = j;\n\t\t\tztex_slave->root = ztex_devices[i]->dev;\n\t\t\tztex_slave->repr[strlen(ztex_slave->repr) - 1] = ('1' + j);\n\t\t\tadd_cgpu(ztex);\n\t\t}\n\n\t\tapplog(LOG_WARNING,\"%s: Found Ztex (fpga count = %d) , mark as %d\", ztex->device_ztex->repr, fpgacount, ztex->device_id);\n\t}\n\n\tif (cnt > 0)\n\t\tlibztex_freeDevList(ztex_devices);\n}\n\nstatic bool ztex_updateFreq(struct libztex_device* ztex)\n{\n\tint i, maxM, bestM;\n\tdouble bestR, r;\n\n\tfor (i = 0; i < ztex->freqMaxM; i++)\n\t\tif (ztex->maxErrorRate[i + 1] * i < ztex->maxErrorRate[i] * (i + 20))\n\t\t\tztex->maxErrorRate[i + 1] = ztex->maxErrorRate[i] * (1.0 + 20.0 / i);\n\n\tmaxM = 0;\n\twhile (maxM < ztex->freqMDefault && ztex->maxErrorRate[maxM + 1] < LIBZTEX_MAXMAXERRORRATE)\n\t\tmaxM++;\n\twhile (maxM < ztex->freqMaxM && ztex->errorWeight[maxM] > 150 && ztex->maxErrorRate[maxM + 1] < LIBZTEX_MAXMAXERRORRATE)\n\t\tmaxM++;\n\n\tbestM = 0;\n\tbestR = 0;\n\tfor (i = 0; i <= maxM; i++) {\n\t\tr = (i + 1 + (i == ztex->freqM? LIBZTEX_ERRORHYSTERESIS: 0)) * (1 - ztex->maxErrorRate[i]);\n\t\tif (r > bestR) {\n\t\t\tbestM = i;\n\t\t\tbestR = r;\n\t\t}\n\t}\n\n\tif (bestM != ztex->freqM) {\n\t\tztex_selectFpga(ztex);\n\t\tlibztex_setFreq(ztex, bestM);\n\t\tztex_releaseFpga(ztex);\n\t}\n\n\tmaxM = ztex->freqMDefault;\n\twhile (maxM < ztex->freqMaxM && ztex->errorWeight[maxM + 1] > 100)\n\t\tmaxM++;\n\tif ((bestM < (1.0 - LIBZTEX_OVERHEATTHRESHOLD) * maxM) && bestM < maxM - 1) {\n\t\tztex_selectFpga(ztex);\n\t\tlibztex_resetFpga(ztex);\n\t\tztex_releaseFpga(ztex);\n\t\tapplog(LOG_ERR, \"%s: frequency drop of %.1f%% detect. This may be caused by overheating. FPGA is shut down to prevent damage.\",\n\t\t       ztex->repr, (1.0 - 1.0 * bestM / maxM) * 100);\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n\n/* ztex_checkNonce moved to cgminer.c for blake\n\nstatic uint32_t ztex_checkNonce(struct work *work, uint32_t nonce)\n{\n\tuint32_t *data32 = (uint32_t *)(work->data);\n\tunsigned char swap[80];\n\tuint32_t *swap32 = (uint32_t *)swap;\n\tunsigned char hash1[32];\n\tunsigned char hash2[32];\n\tuint32_t *hash2_32 = (uint32_t *)hash2;\n\tint i;\n\n\tswap32[76/4] = htonl(nonce);\n\n\tfor (i = 0; i < 76 / 4; i++)\n\t\tswap32[i] = swab32(data32[i]);\n\n\tsha2(swap, 80, hash1);\n\tsha2(hash1, 32, hash2);\n\n\treturn htonl(hash2_32[7]);\n}\n*/\n\nstatic int64_t ztex_scanhash(struct thr_info *thr, struct work *work,\n                              __maybe_unused int64_t max_nonce)\n{\n\n\t// int numbytes = 80;\t\t\t// KRAMBLE 80 byte protocol\n\tint numbytes = 76;\t\t\t\t// KRAMBLE 76 byte protocol\n\n\tstruct libztex_device *ztex;\n\tunsigned char sendbuf[80];\t\t// KRAMBLE\n\tint i, j, k;\n\tuint32_t *backlog;\n\tint backlog_p = 0, backlog_max;\n\tuint32_t *lastnonce;\n\tuint32_t nonce, noncecnt = 0;\n\tbool overflow, found;\n\tstruct libztex_hash_data hdata[GOLDEN_BACKLOG];\n\n\tif (thr->cgpu->deven == DEV_DISABLED)\n\t\treturn -1;\n\n\tztex = thr->cgpu->device_ztex;\n\n\t// memcpy(sendbuf, work->data + 64, 12);\n\t// memcpy(sendbuf + 12, work->midstate, 32);\n\tmemcpy(sendbuf, work->data, numbytes);\t// KRAMBLE\n\n\tztex_selectFpga(ztex);\n\ti = libztex_sendHashData(ztex, sendbuf, numbytes);\n\tif (i < 0) {\n\t\t// Something wrong happened in send\n\t\tapplog(LOG_ERR, \"%s: Failed to send hash data with err %d, retrying\", ztex->repr, i);\n\t\tnmsleep(500);\n\t\ti = libztex_sendHashData(ztex, sendbuf, numbytes);\n\t\tif (i < 0) {\n\t\t\t// And there's nothing we can do about it\n\t\t\tztex_disable(thr);\n\t\t\tapplog(LOG_ERR, \"%s: Failed to send hash data with err %d, giving up\", ztex->repr, i);\n\t\t\tztex_releaseFpga(ztex);\n\t\t\treturn -1;\n\t\t}\n\t}\n\tztex_releaseFpga(ztex);\n\n#if 0\t// KRAMBLE\n\tchar *data = bin2hex(work->data, sizeof(work->data));\n\tapplog(LOG_INFO, \"%s: sent data %s\", ztex->repr, data);\n#endif\n\n\tlastnonce = calloc(1, sizeof(uint32_t)*ztex->numNonces);\n\tif (lastnonce == NULL) {\n\t\tapplog(LOG_ERR, \"%s: failed to allocate lastnonce[%d]\", ztex->repr, ztex->numNonces);\n\t\treturn -1;\n\t}\n\n\t/* Add an extra slot for detecting dupes that lie around */\n\tbacklog_max = ztex->numNonces * (2 + ztex->extraSolutions);\n\tbacklog = calloc(1, sizeof(uint32_t) * backlog_max);\n\tif (backlog == NULL) {\n\t\tapplog(LOG_ERR, \"%s: failed to allocate backlog[%d]\", ztex->repr, backlog_max);\n\t\treturn -1;\n\t}\n\n\toverflow = false;\n\tint count = 0;\n\tint validNonces = 0;\n\tdouble errorCount = 0;\n\n\tapplog(LOG_DEBUG, \"%s: entering poll loop\", ztex->repr);\n\twhile (!(overflow || thr->work_restart)) {\n\t\tcount++;\n\n\t\tint sleepcount = 0;\n\t\twhile (thr->work_restart == 0 && sleepcount < 25) {\n\t\t\tnmsleep(10);\n\t\t\tsleepcount += 1;\n\t\t}\n\n\t\tif (thr->work_restart) {\n\t\t\tapplog(LOG_DEBUG, \"%s: New work detected\", ztex->repr);\n\t\t\tbreak;\n\t\t}\n\n\t\tztex_selectFpga(ztex);\n\t\ti = libztex_readHashData(ztex, &hdata[0]);\n\t\tif (i < 0) {\n\t\t\t// Something wrong happened in read\n\t\t\tapplog(LOG_ERR, \"%s: Failed to read hash data with err %d, retrying\", ztex->repr, i);\n\t\t\tnmsleep(500);\n\t\t\ti = libztex_readHashData(ztex, &hdata[0]);\n\t\t\tif (i < 0) {\n\t\t\t\t// And there's nothing we can do about it\n\t\t\t\tztex_disable(thr);\n\t\t\t\tapplog(LOG_ERR, \"%s: Failed to read hash data with err %d, giving up\", ztex->repr, i);\n\t\t\t\tfree(lastnonce);\n\t\t\t\tfree(backlog);\n\t\t\t\tztex_releaseFpga(ztex);\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\tztex_releaseFpga(ztex);\n\n\t\tif (thr->work_restart) {\n\t\t\tapplog(LOG_DEBUG, \"%s: New work detected\", ztex->repr);\n\t\t\tbreak;\n\t\t}\n\n\t\tztex->errorCount[ztex->freqM] *= 0.995;\n\t\tztex->errorWeight[ztex->freqM] = ztex->errorWeight[ztex->freqM] * 0.995 + 1.0;\n\n\t\tfor (i = 0; i < ztex->numNonces; i++) {\n\t\t\tnonce = hdata[i].nonce;\n\t\t\tif (nonce > noncecnt)\n\t\t\t\tnoncecnt = nonce;\n\t\t\t// KRAMBLE don't overflow if nonce == 0 (eg if fpga is not hashing)\n\t\t\tif ( (((0xffffffff - nonce) < (nonce - lastnonce[i])) || nonce < lastnonce[i]) && nonce ) {\n\t\t\t\tapplog(LOG_INFO, \"%s: overflow nonce=%08x lastnonce=%08x\", ztex->repr, nonce, lastnonce[i]);\t// KRAMBLE not in production ??\n\t\t\t\t// applog(LOG_DEBUG, \"%s: overflow nonce=%08x lastnonce=%08x\", ztex->repr, nonce, lastnonce[i]);\n\t\t\t\t// overflow = true;\t\t// KRAMBLE disabled as it should not happen at litecoin hash rates (except when broken\n\t\t\t\t\t\t\t\t\t\t// so leave warning message enabled)\n\t\t\t} else\n\t\t\t\tlastnonce[i] = nonce;\n\t\t\t\t\n\t\t\t// KRAMBLE try forcing overflow every so often to see if this fixes DIFF & SICK problems\n\t\t\t// if (nonce > 0x00040000)\t// Overflow every 256k nonces (a few times a minute, depending on hash rate)\n\t\t\tif (nonce > 0x00100000)\t// Overflow every 1M nonces (single core needs larger range to avoid duplicates)\n\t\t\t{\n\t\t\t\t// applog(LOG_INFO, \"%s: force overflow nonce=%08x lastnonce=%08x\", ztex->repr, nonce, lastnonce[i]);\t// KRAMBLE not in production\n \t\t\t\toverflow = true;\n\t\t\t}\n\n\t\t\tif (ztex_checkNonce(work, nonce) != (hdata->hash7)) {\n\t\t\t\tapplog(LOG_INFO, \"%s: checkNonce failed for %08X hash7 %08X\", ztex->repr, nonce, hdata->hash7);\t\t// KRAMBLE not in production ??\n\t\t\t\t// applog(LOG_DEBUG, \"%s: checkNonce failed for %08X\", ztex->repr, nonce);\n\n\t\t\t\t// do not count errors in the first 500ms after sendHashData (2x250 wait time)\n\t\t\t\tif (count > 2) {\n\t\t\t\t\n\t\t\t\t\tthr->cgpu->hw_errors++;\n\t\t\t\t\terrorCount += (1.0 / ztex->numNonces);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tvalidNonces++;\n\n\t\t\tfor (j=0; j<=ztex->extraSolutions; j++) {\n\t\t\t\tnonce = hdata[i].goldenNonce[j];\n\n\t\t\t\tif (nonce == ztex->offsNonces) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// precheck the extraSolutions since they often fail\n\t\t\t\tif (j > 0 && ztex_checkNonce(work, nonce) != 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tfound = false;\n\t\t\t\tfor (k = 0; k < backlog_max; k++) {\n\t\t\t\t\tif (backlog[k] == nonce) {\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!found) {\n\t\t\t\t\tapplog(LOG_INFO, \"%s: Share found %08x\", ztex->repr, nonce);\t\t// KRAMBLE useful to show its working\n\t\t\t\t\t// applog(LOG_DEBUG, \"%s: Share found N%dE%d\", ztex->repr, i, j);\n\t\t\t\t\tbacklog[backlog_p++] = nonce;\n\n\t\t\t\t\tif (backlog_p >= backlog_max)\n\t\t\t\t\t\tbacklog_p = 0;\n\n\t\t\t\t\twork->blk.nonce = 0xffffffff;\n\t\t\t\t\tsubmit_nonce(thr, work, nonce);\n\t\t\t\t\tapplog(LOG_DEBUG, \"%s: submitted %08x\", ztex->repr, nonce);\t\t\t\t\t\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// only add the errorCount if we had at least some valid nonces or\n\t// had no valid nonces in the last round\n\tif (errorCount > 0.0) {\n\t\tif (ztex->nonceCheckValid > 0 && validNonces == 0) {\n\t\t\tapplog(LOG_ERR, \"%s: resetting %.1f errors\", ztex->repr, errorCount);\n\t\t}\n\t\telse {\n\t\t\tztex->errorCount[ztex->freqM] += errorCount;\n\t\t}\n\t}\n\n\t// remember the number of valid nonces for the check in the next round\n\tztex->nonceCheckValid = validNonces;\n\n\tztex->errorRate[ztex->freqM] = ztex->errorCount[ztex->freqM] /\tztex->errorWeight[ztex->freqM] * (ztex->errorWeight[ztex->freqM] < 100? ztex->errorWeight[ztex->freqM] * 0.01: 1.0);\n\tif (ztex->errorRate[ztex->freqM] > ztex->maxErrorRate[ztex->freqM])\n\t\tztex->maxErrorRate[ztex->freqM] = ztex->errorRate[ztex->freqM];\n\n\t// KRAMBLE Disable ztex_updateFreq if lockClock flag set (ie --ztex-clock set initial and max freq to the same value)\n\tif (!ztex->lockClock) {\n\t\tif (!ztex_updateFreq(ztex)) {\n\t\t\t// Something really serious happened, so mark this thread as dead!\n\t\t\tfree(lastnonce);\n\t\t\tfree(backlog);\n\t\t\t\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\tapplog(LOG_DEBUG, \"%s: exit %1.8X\", ztex->repr, noncecnt);\n\n\twork->blk.nonce = 0xffffffff;\n\n\tfree(lastnonce);\n\tfree(backlog);\n\n\treturn noncecnt;\n}\n\nstatic void ztex_statline_before(char *buf, struct cgpu_info *cgpu)\n{\n\tif (cgpu->deven == DEV_ENABLED) {\n\t\ttailsprintf(buf, \"%s-%d | \", cgpu->device_ztex->snString, cgpu->device_ztex->fpgaNum+1);\n\t\ttailsprintf(buf, \"%0.1fMHz | \", cgpu->device_ztex->freqM1 * (cgpu->device_ztex->freqM + 1));\n\t}\n}\n\nstatic bool ztex_prepare(struct thr_info *thr)\n{\n\tstruct timeval now;\n\tstruct cgpu_info *cgpu = thr->cgpu;\n\tstruct libztex_device *ztex = cgpu->device_ztex;\n\n\tcgtime(&now);\n\tget_datestamp(cgpu->init, &now);\n\n\tztex_selectFpga(ztex);\n\tif (libztex_configureFpga(ztex) != 0) {\n\t\tlibztex_resetFpga(ztex);\n\t\tztex_releaseFpga(ztex);\n\t\tapplog(LOG_ERR, \"%s: Disabling!\", thr->cgpu->device_ztex->repr);\n\t\tthr->cgpu->deven = DEV_DISABLED;\n\t\treturn true;\n\t}\n\t\n\t// KRAMBLE Handle options, based on get_options in driver-icarus.c\n\t// Use as --ztex-clock freqM:freqMaxM\n\t// Multiple comma separated vaues are allowed eg 160:180,180:184\n\n\t{\t// Bare block to isolate variables\n\n\t\tchar err_buf[BUFSIZ+1];\n\t\tchar buf[BUFSIZ+1];\n\t\tchar *ptr, *comma, *colon, *colon2;\n\t\tsize_t max;\n\t\tint i, tmp;\n\n\t\tint this_option_offset = ++option_offset;\n\n\t\tif (opt_ztex_clock == NULL)\n\t\t\t\tbuf[0] = '\\0';\n\t\telse {\n\t\t\tptr = opt_ztex_clock;\n\t\t\tfor (i = 0; i < this_option_offset; i++) {\n\t\t\t\tcomma = strchr(ptr, ',');\n\t\t\t\tif (comma == NULL)\n\t\t\t\t\tbreak;\n\t\t\t\tptr = comma + 1;\n\t\t\t}\n\n\t\t\tcomma = strchr(ptr, ',');\n\t\t\tif (comma == NULL)\n\t\t\t\tmax = strlen(ptr);\n\t\t\telse\n\t\t\t\tmax = comma - ptr;\n\n\t\t\tif (max > BUFSIZ)\n\t\t\t\tmax = BUFSIZ;\n\t\t\tstrncpy(buf, ptr, max);\n\t\t\tbuf[max] = '\\0';\n\t\t}\n\n\n\t\tif (*buf) {\n\t\t\tcolon = strchr(buf, ':');\n\t\t\tif (colon)\n\t\t\t\t*(colon++) = '\\0';\n\n\t\t\tif (*buf) {\n\t\t\t\ttmp = atoi(buf);\n\t\t\t\tif (tmp >= 100 && tmp <= 250)\n\t\t\t\t\tztex->freqM = ztex->freqMDefault = tmp/4 - 1;\t// NB 4Mhz units\n\t\t\t\telse {\n\t\t\t\t\tsprintf(err_buf, \"Invalid ztex_clock must be between 100 and 250\", buf);\n\t\t\t\t\tquit(1, err_buf);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (colon && *colon) {\n\t\t\t\ttmp = atoi(colon);\n\t\t\t\tif (tmp >= 100 && tmp <= 250) {\n\t\t\t\t\tif (tmp/4 - 1 >= ztex->freqM)\n\t\t\t\t\t{\n\t\t\t\t\t\tztex->freqMaxM = tmp/4 - 1;\t// NB 4Mhz units\n\t\t\t\t\t\t// If both initial and max were set, and were the same, lock the clock\n\t\t\t\t\t\tif (ztex->freqMDefault == ztex->freqMaxM)\n\t\t\t\t\t\t\tztex->lockClock = 1;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tsprintf(err_buf, \"Invalid ztex_clock max must be less than min\", buf);\n\t\t\t\t\t\tquit(1, err_buf);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tsprintf(err_buf, \"Invalid ztex_clock must be between 100 and 250\", buf);\n\t\t\t\t\tquit(1, err_buf);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t}\t// End bare block\n\t\n\t\n\tztex->freqM = ztex->freqMaxM+1;\t\t// KRAMBLE is in original\n\t// ztex_updateFreq(ztex);\t\t\t// KRAMBLE Was already commented out in original\n\n#if 1\n\tlibztex_setFreq(ztex, ztex->freqMDefault);\t\t\t// KRAMBLE PRODUCTION CODE\n#else\n\t// KRAMBLE build customised settings for a specific board\n\tif (ztex->repr[strlen(ztex->repr)-1] == '4')\n\t\tlibztex_setFreq(ztex, ztex->freqMDefault-1);\t// Run it 4MHz slower\n\telse\n\t\tlibztex_setFreq(ztex, ztex->freqMDefault);\n#endif\n\n\tztex_releaseFpga(ztex);\n\tapplog(LOG_DEBUG, \"%s: prepare\", ztex->repr);\n\treturn true;\n}\n\nstatic void ztex_shutdown(struct thr_info *thr)\n{\n\tif (thr->cgpu->device_ztex != NULL) {\n\t\tif (thr->cgpu->device_ztex->fpgaNum == 0)\n\t\t\tpthread_mutex_destroy(&thr->cgpu->device_ztex->mutex);  \n\t\tapplog(LOG_DEBUG, \"%s: shutdown\", thr->cgpu->device_ztex->repr);\n\t\tlibztex_destroy_device(thr->cgpu->device_ztex);\n\t\tthr->cgpu->device_ztex = NULL;\n\t}\n}\n\nstatic void ztex_disable(struct thr_info *thr)\n{\n\tstruct cgpu_info *cgpu;\n\n\tapplog(LOG_ERR, \"%s: Disabling!\", thr->cgpu->device_ztex->repr);\n\tcgpu = get_devices(thr->cgpu->device_id);\n\tcgpu->deven = DEV_DISABLED;\n\tztex_shutdown(thr);\n}\n\nstruct device_drv ztex_drv = {\n\t.drv_id = DRIVER_ZTEX,\n\t.dname = \"ztex\",\n\t.name = \"ZTX\",\n\t.drv_detect = ztex_detect,\n\t.get_statline_before = ztex_statline_before,\n\t.thread_prepare = ztex_prepare,\n\t.scanhash = ztex_scanhash,\n\t.thread_shutdown = ztex_shutdown,\n};\n\n"
  },
  {
    "path": "experimental/Ztex-1-15y/cgminer-3.1.1/libztex.c",
    "content": "/**\n *   libztex.c - Ztex 1.15x/1.15y fpga board support library\n *\n *   Copyright (c) 2012 nelisky.btc@gmail.com\n *   Copyright (c) 2012 Denis Ahrens <denis@h3q.com>\n *   Copyright (c) 2012 Peter Stuge <peter@stuge.se>\n *\n *   This work is based upon the Java SDK provided by ztex which is\n *   Copyright (C) 2009-2011 ZTEX GmbH.\n *   http://www.ztex.de\n *\n *   This program is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License version 2 as\n *   published by the Free Software Foundation.\n *\n *   This program is distributed in the hope that it will be useful, but\n *   WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n *   General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program; if not, see http://www.gnu.org/licenses/.\n**/\n\n#include \"config.h\"\n\n#include <stdio.h>\n#include <unistd.h>\n#include <string.h>\n\n#include \"miner.h\"\n#include \"fpgautils.h\"\n#include \"libztex.h\"\n\n//* Capability index for EEPROM support.\n#define CAPABILITY_EEPROM 0,0\n//* Capability index for FPGA configuration support. \n#define CAPABILITY_FPGA 0,1\n//* Capability index for FLASH memory support.\n#define CAPABILITY_FLASH 0,2\n//* Capability index for DEBUG helper support.\n#define CAPABILITY_DEBUG 0,3\n//* Capability index for AVR XMEGA support.\n#define CAPABILITY_XMEGA 0,4\n//* Capability index for AVR XMEGA support.\n#define CAPABILITY_HS_FPGA 0,5\n//* Capability index for AVR XMEGA support.\n#define CAPABILITY_MAC_EEPROM 0,6\n//* Capability index for multi FPGA support.\n#define CAPABILITY_MULTI_FPGA 0,7\n\nstatic int libztex_get_string_descriptor_ascii(libusb_device_handle *dev, uint8_t desc_index,\n\t\tunsigned char *data, int length)\n{\n\tint i, cnt;\n\tuint16_t langid;\n\tunsigned char buf[260];\n\n\t/* We open code string descriptor retrieval and ASCII decoding here\n\t * in order to work around that libusb_get_string_descriptor_ascii()\n\t * in the FreeBSD libusb implementation hits a bug in ZTEX firmware,\n\t * where the device returns more bytes than requested, causing babble,\n\t * which makes FreeBSD return an error to us.\n\t *\n\t * Avoid the mess by doing it manually the same way as libusb-1.0.\n\t */\n\n\tcnt = libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN,\n\t    LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | 0,\n\t    0x0000, buf, sizeof(buf), 1000);\n\tif (cnt < 0) {\n\t\tapplog(LOG_ERR, \"%s: Failed to read LANGIDs: %d\", __func__, cnt);\n\t\treturn cnt;\n\t}\n\n\tlangid = libusb_le16_to_cpu(((uint16_t *)buf)[1]);\n\n\tcnt = libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN,\n\t    LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | desc_index,\n\t    langid, buf, sizeof(buf), 1000);\n\tif (cnt < 0) {\n\t\tapplog(LOG_ERR, \"%s: Failed to read string descriptor: %d\", __func__, cnt);\n\t\treturn cnt;\n\t}\n\n\t/* num chars = (all bytes except bLength and bDescriptorType) / 2 */\n\tfor (i = 0; i <= (cnt - 2) / 2 && i < length-1; i++)\n\t\tdata[i] = buf[2 + i*2];\n\n\tdata[i] = 0;\n\n\treturn LIBUSB_SUCCESS;\n}\n\nenum check_result\n{\n\tCHECK_ERROR,\n\tCHECK_IS_NOT_ZTEX,\n\tCHECK_OK,\n\tCHECK_RESCAN,\n};\n\nstatic bool libztex_firmwareReset(struct libusb_device_handle *hndl, bool enable)\n{\n\tuint8_t reset = enable;\n\tint cnt = libusb_control_transfer(hndl, 0x40, 0xA0, 0xE600, 0, &reset, 1, 1000);\n\tif (cnt < 0)\n\t{\n\t\tapplog(LOG_ERR, \"Ztex reset %d failed: %d\", enable, cnt);\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\nstatic enum check_result libztex_checkDevice(struct libusb_device *dev)\n{\n\tFILE *fp = NULL;\n\tlibusb_device_handle *hndl = NULL;\n\tstruct libusb_device_descriptor desc;\n\tint ret = CHECK_ERROR, err, cnt;\n\tsize_t got_bytes, length;\n\tunsigned char buf[64], *fw_buf;\n\tunsigned int i;\n\n\terr = libusb_get_device_descriptor(dev, &desc);\n\tif (unlikely(err != 0)) {\n\t\tapplog(LOG_ERR, \"Ztex check device: Failed to open read descriptor with error %d\", err);\n\t\treturn CHECK_ERROR;\n\t}\n\n\tif (desc.idVendor != LIBZTEX_IDVENDOR || desc.idProduct != LIBZTEX_IDPRODUCT) {\n\t\tapplog(LOG_DEBUG, \"Not a ZTEX device %04x:%04x\", desc.idVendor, desc.idProduct);\n\t\treturn CHECK_IS_NOT_ZTEX;\n\t}\n\n\terr = libusb_open(dev, &hndl);\n\tif (err != LIBUSB_SUCCESS) {\n\t\tapplog(LOG_ERR, \"%s: Can not open ZTEX device: %d\", __func__, err);\n\t\tgoto done;\n\t}\n\n\tcnt = libusb_control_transfer(hndl, 0xc0, 0x22, 0, 0, buf, 40, 500);\n\tif (unlikely(cnt < 0)) {\n\t\tapplog(LOG_ERR, \"Ztex check device: Failed to read ztex descriptor with err %d\", cnt);\n\t\tgoto done;\n\t}\n\n\tif (buf[0] != 40 || buf[1] != 1 || buf[2] != 'Z' || buf[3] != 'T' || buf[4] != 'E' || buf[5] != 'X') {\n\t\tapplog(LOG_ERR, \"Ztex check device: Error reading ztex descriptor\");\n\t\tgoto done;\n\t}\n\n\tif (buf[6] != 10)\n\t{\n\t\tret = CHECK_IS_NOT_ZTEX;\n\t\tgoto done;\n\t}\n\n\t// 15 = 1.15y   13 = 1.15d or 1.15x\n\tswitch(buf[7])\n\t{\n\t\tcase 13:\n\t\t\tapplog(LOG_ERR, \"Found ztex board 1.15d or 1.15x\");\n\t\t\tbreak;\n\t\tcase 15:\n\t\t\tapplog(LOG_ERR, \"Found ztex board 1.15y\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tapplog(LOG_ERR, \"Found unknown ztex board\");\n\t\t\tret = CHECK_IS_NOT_ZTEX;\n\t\t\tgoto done;\n\t}\n\n\t// testing for dummy firmware\n\tif (buf[8] != 0) {\n\t\tret = CHECK_OK;\n\t\tgoto done;\n\t}\n\n\tapplog(LOG_ERR, \"Found dummy firmware, trying to send mining firmware\");\n\n\tchar productString[32];\n\n\tcnt = libztex_get_string_descriptor_ascii(hndl, desc.iProduct, (unsigned char*)productString, sizeof(productString));\n\tif (unlikely(cnt < 0)) {\n\t\tapplog(LOG_ERR, \"Ztex check device: Failed to read device productString with err %d\", cnt);\n\t\treturn cnt;\n\t}\n\n\tapplog(LOG_ERR, \"productString: %s\", productString);\n\n\tunsigned char productID2 = buf[7];\n\tchar *firmware = NULL;\n\n\tif (strcmp(\"USB-FPGA Module 1.15d (default)\", productString) == 0 && productID2 == 13)\n\t{\n\t\tfirmware = \"ztex_ufm1_15d4.bin\";\n\t}\n\telse if (strcmp(\"USB-FPGA Module 1.15x (default)\", productString) == 0 && productID2 == 13)\n\t{\n\t\tfirmware = \"ztex_ufm1_15d4.bin\";\n\t}\n\telse if (strcmp(\"USB-FPGA Module 1.15y (default)\", productString) == 0 && productID2 == 15)\n\t{\n\t\tfirmware = \"ztex_ufm1_15y1.bin\";\n\t}\n\n\tif (firmware == NULL)\n\t{\n\t\tapplog(LOG_ERR, \"could not figure out which firmware to use\");\n\t\tgoto done;\n\t}\n\n\tapplog(LOG_ERR, \"Mining firmware filename: %s\", firmware);\n\n\tfp = open_bitstream(\"ztex\", firmware);\n\tif (!fp) {\n\t\tapplog(LOG_ERR, \"failed to open firmware file '%s'\", firmware);\n\t\tgoto done;\n\t}\n\n\tif (0 != fseek(fp, 0, SEEK_END)) {\n\t\tapplog(LOG_ERR, \"Ztex firmware fseek: %s\", strerror(errno));\n\t\tgoto done;\n\t}\n\n\tlength = ftell(fp);\n\trewind(fp);\n\tfw_buf = malloc(length);\n\tif (!fw_buf) {\n\t\tapplog(LOG_ERR, \"%s: Can not allocate memory: %s\", __func__, strerror(errno));\n\t\tgoto done;\n\t}\n\n\tgot_bytes = fread(fw_buf, 1, length, fp);\n\tfclose(fp);\n\tfp = NULL;\n\n\tif (got_bytes < length) {\n\t\tapplog(LOG_ERR, \"%s: Incomplete firmware read: %zu/%zu\", __func__, got_bytes, length);\n\t\tgoto done;\n\t}\n\n\t// in buf[] is still the identifier of the dummy firmware\n\t// use it to compare it with the new firmware\n\tchar *rv = memmem(fw_buf, got_bytes, buf, 8);\n\tif (rv == NULL)\n\t{\n\t\tapplog(LOG_ERR, \"%s: found firmware is not ZTEX\", __func__);\n\t\tgoto done;\n\t}\n\n\t// check for dummy firmware\n\tif (rv[8] == 0)\n\t{\n\t\tapplog(LOG_ERR, \"%s: found a ZTEX dummy firmware\", __func__);\n\t\tgoto done;\n\t}\n\n\tif (libztex_firmwareReset(hndl, true))\n\t\tgoto done;\n\n\tfor (i = 0; i < length; i+= 256) {\n\t\t// firmware wants data in small chunks like 256 bytes\n\t\tint numbytes = (length - i) < 256 ? (length - i) : 256;\n\t\tint k = libusb_control_transfer(hndl, 0x40, 0xA0, i, 0, fw_buf + i, numbytes, 1000);\n\t\tif (k < numbytes)\n\t\t{\n\t\t\tapplog(LOG_ERR, \"Ztex device: Failed to write firmware at %d with err: %d\", i, k);\n\t\t\tgoto done;\n\t\t}\n\t}\n\n\tif (libztex_firmwareReset(hndl, false))\n\t\tgoto done;\n\n\tapplog(LOG_ERR, \"Ztex device: succesfully wrote firmware\");\n\tret = CHECK_RESCAN;\n\ndone:\n\tif (fp)\n\t\tfclose(fp);\n\tif (hndl)\n\t\tlibusb_close(hndl);\n\treturn ret;\n}\n\nstatic bool libztex_checkCapability(struct libztex_device *ztex, int i, int j)\n{\n\tif (!((i >= 0) && (i <= 5) && (j >= 0) && (j < 8) &&\n\t     (((ztex->interfaceCapabilities[i] & 255) & (1 << j)) != 0))) {\n\t\tapplog(LOG_ERR, \"%s: capability missing: %d %d\", ztex->repr, i, j);\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nstatic char libztex_detectBitstreamBitOrder(const unsigned char *buf, int size)\n{\n\tint i;\n\n\tfor (i = 0; i < size - 4; i++) {\n\t\tif (((buf[i] & 255) == 0xaa) && ((buf[i + 1] & 255) == 0x99) && ((buf[i + 2] & 255) == 0x55) && ((buf[i + 3] & 255) == 0x66))\n\t\t\treturn 1;\n\t\tif (((buf[i] & 255) == 0x55) && ((buf[i + 1] & 255) == 0x99) && ((buf[i + 2] & 255) == 0xaa) && ((buf[i + 3] & 255) == 0x66))\n\t\t\treturn 0;\n\t} \n\tapplog(LOG_WARNING, \"Unable to determine bitstream bit order: no signature found\");\n\treturn 0;\n}\n\nstatic void libztex_swapBits(unsigned char *buf, int size)\n{\n\tunsigned char c;\n\tint i;\n\n\tfor (i = 0; i < size; i++) {\n\t\tc = buf[i];\n\t\tbuf[i] = ((c & 128) >> 7) |\n\t\t         ((c & 64) >> 5) |\n\t\t         ((c & 32) >> 3) |\n\t\t         ((c & 16) >> 1) |\n\t\t         ((c & 8) << 1) |\n\t\t         ((c & 4) << 3) |\n\t\t         ((c & 2) << 5) |\n\t\t         ((c & 1) << 7);\n\t}\n}\n\nstatic int libztex_getFpgaState(struct libztex_device *ztex, struct libztex_fpgastate *state)\n{\n\tunsigned char buf[9];\n\tint cnt;\n\n\tif (!libztex_checkCapability(ztex, CAPABILITY_FPGA))\n\t\treturn -1;\n\tcnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x30, 0, 0, buf, 9, 1000);\n\tif (unlikely(cnt < 0)) {\n\t\tapplog(LOG_ERR, \"%s: Failed getFpgaState with err %d\", ztex->repr, cnt);\n\t\treturn cnt;\n\t}\n\tstate->fpgaConfigured = (buf[0] == 0);\n\tstate->fpgaChecksum = buf[1] & 0xff;\n\tstate->fpgaBytes = ((buf[5] & 0xff) << 24) | ((buf[4] & 0xff) << 16) | ((buf[3] & 0xff) << 8) | (buf[2] & 0xff);\n\tstate->fpgaInitB = buf[6] & 0xff;\n\tstate->fpgaFlashResult = buf[7];\n\tstate->fpgaFlashBitSwap = (buf[8] != 0);\n\treturn 0;\n}\n\nstatic int libztex_configureFpgaHS(struct libztex_device *ztex, const char* firmware, bool force, char bs)\n{\n\tstruct libztex_fpgastate state;\n\tconst int transactionBytes = 65536;\n\tunsigned char buf[transactionBytes], settings[2];\n\tint tries, cnt, err;\n\tFILE *fp;\n\n\tif (!libztex_checkCapability(ztex, CAPABILITY_HS_FPGA))\n\t\treturn -1;\n\tlibztex_getFpgaState(ztex, &state);\n\tif (!force && state.fpgaConfigured) {\n\t\tapplog(LOG_INFO, \"Bitstream already configured\");\n\t\treturn 0;\n\t}\n\tcnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x33, 0, 0, settings, 2, 1000);\n\tif (unlikely(cnt < 0)) {\n\t\tapplog(LOG_ERR, \"%s: Failed getHSFpgaSettings with err %d\", ztex->repr, cnt);\n\t\treturn cnt;\n\t}\n\n\terr = libusb_claim_interface(ztex->hndl, settings[1]);\n\tif (err != LIBUSB_SUCCESS) {\n\t\tapplog(LOG_ERR, \"%s: failed to claim interface for hs transfer\", ztex->repr);\n\t\treturn -4;\n\t}\n\n\tfor (tries = 3; tries > 0; tries--) {\n\t\tfp = open_bitstream(\"ztex\", firmware);\n\t\tif (!fp) {\n\t\t\tapplog(LOG_ERR, \"%s: failed to read bitstream '%s'\", ztex->repr, firmware);\n\t\t\tlibusb_release_interface(ztex->hndl, settings[1]);\n\t\t\treturn -2;\n\t\t}\n\n\t\tlibusb_control_transfer(ztex->hndl, 0x40, 0x34, 0, 0, NULL, 0, 1000);\n\t\t// 0x34 - initHSFPGAConfiguration\n\n\t\tdo\n\t\t{\n\t\t\tint length = fread(buf,1,transactionBytes,fp);\n\n\t\t\tif (bs != 0 && bs != 1)\n\t\t\t\tbs = libztex_detectBitstreamBitOrder(buf, length);\n\t\t\tif (bs == 1)\n\t\t\t\tlibztex_swapBits(buf, length);\n\n\t\t\terr = libusb_bulk_transfer(ztex->hndl, settings[0], buf, length, &cnt, 1000);\n\t\t\tif (cnt != length)\n\t\t\t\tapplog(LOG_ERR, \"%s: cnt != length\", ztex->repr);\n\t\t\tif (err != 0)\n\t\t\t\tapplog(LOG_ERR, \"%s: Failed send hs fpga data\", ztex->repr);\n\t\t}\n\t\twhile (!feof(fp));\n\n\t\tlibusb_control_transfer(ztex->hndl, 0x40, 0x35, 0, 0, NULL, 0, 1000);\n\t\t// 0x35 - finishHSFPGAConfiguration\n\t\tif (cnt >= 0)\n\t\t\ttries = 0;\n\n\t\tfclose(fp);\n\n\t\tlibztex_getFpgaState(ztex, &state);\n\t\tif (!state.fpgaConfigured) {\n\t\t\tapplog(LOG_ERR, \"%s: HS FPGA configuration failed: DONE pin does not go high\", ztex->repr);\n\t\t\tlibusb_release_interface(ztex->hndl, settings[1]);\n\t\t\treturn -3;\n\t\t}\n\t}\n\n\tlibusb_release_interface(ztex->hndl, settings[1]);\n\n\tnmsleep(200);\n\tapplog(LOG_INFO, \"%s: HS FPGA configuration done\", ztex->repr);\n\treturn 0;\n}\n\nstatic int libztex_configureFpgaLS(struct libztex_device *ztex, const char* firmware, bool force, char bs)\n{\n\tstruct libztex_fpgastate state;\n\tconst int transactionBytes = 2048;\n\tunsigned char buf[transactionBytes];\n\tint tries, cnt;\n\tFILE *fp;\n\n\tif (!libztex_checkCapability(ztex, CAPABILITY_FPGA))\n\t\treturn -1;\n\n\tlibztex_getFpgaState(ztex, &state);\n\tif (!force && state.fpgaConfigured) {\n\t\tapplog(LOG_DEBUG, \"Bitstream already configured\");\n\t\treturn 0;\n\t}\n\n\tfor (tries = 10; tries > 0; tries--) {\n\t\tfp = open_bitstream(\"ztex\", firmware);\n\t\tif (!fp) {\n\t\t\tapplog(LOG_ERR, \"%s: failed to read bitstream '%s'\", ztex->repr, firmware);\n\t\t\treturn -2;\n\t\t}\n\n\t\t//* Reset fpga\n\t\tcnt = libztex_resetFpga(ztex);\n\t\tif (unlikely(cnt < 0)) {\n\t\t\tapplog(LOG_ERR, \"%s: Failed reset fpga with err %d\", ztex->repr, cnt);\n\t\t\tcontinue;\n\t\t}\n\n\t\tdo\n\t\t{\n\t\t\tint length = fread(buf, 1, transactionBytes, fp);\n\n\t\t\tif (bs != 0 && bs != 1)\n\t\t\t\tbs = libztex_detectBitstreamBitOrder(buf, length);\n\t\t\tif (bs == 1)\n\t\t\t\tlibztex_swapBits(buf, length);\n\t\t\tcnt = libusb_control_transfer(ztex->hndl, 0x40, 0x32, 0, 0, buf, length, 5000);\n\t\t\tif (cnt != length)\n\t\t\t{\n\t\t\t\tapplog(LOG_ERR, \"%s: Failed send ls fpga data\", ztex->repr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\twhile (!feof(fp));\n\n\t\tif (cnt > 0)\n\t\t\ttries = 0;\n\n\t\tfclose(fp);\n\t}\n\n\tlibztex_getFpgaState(ztex, &state);\n\tif (!state.fpgaConfigured) {\n\t\tapplog(LOG_ERR, \"%s: LS FPGA configuration failed: DONE pin does not go high\", ztex->repr);\n\t\treturn -3;\n\t}\n\n\tnmsleep(200);\n\tapplog(LOG_INFO, \"%s: FPGA configuration done\", ztex->repr);\n\treturn 0;\n}\n\nint libztex_configureFpga(struct libztex_device *ztex)\n{\n\tchar buf[256];\n\tint rv;\n\n\tstrcpy(buf, ztex->bitFileName);\n\tstrcat(buf, \".bit\");\n\trv = libztex_configureFpgaHS(ztex, buf, true, 2);\n\tif (rv != 0)\n\t\trv = libztex_configureFpgaLS(ztex, buf, true, 2);\n\treturn rv;\n}\n\nint libztex_numberOfFpgas(struct libztex_device *ztex)\n{\n\tint cnt;\n\tunsigned char buf[3];\n\n\tif (ztex->numberOfFpgas < 0) {\n\t\tif (libztex_checkCapability(ztex, CAPABILITY_MULTI_FPGA)) {\n\t\t\tcnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x50, 0, 0, buf, 3, 1000);\n\t\t\tif (unlikely(cnt < 0)) {\n\t\t\t\tapplog(LOG_ERR, \"%s: Failed getMultiFpgaInfo with err %d\", ztex->repr, cnt);\n\t\t\t\treturn cnt;\n\t\t\t}\n\t\t\tztex->numberOfFpgas = buf[0] + 1;\n\t\t\tztex->selectedFpga = -1;//buf[1];\n\t\t\tztex->parallelConfigSupport = (buf[2] == 1);\n\t\t} else {\n\t\t\tztex->numberOfFpgas = 1;\n\t\t\tztex->selectedFpga = -1;//0;\n\t\t\tztex->parallelConfigSupport = false;\n\t\t}\n\t}\n\treturn ztex->numberOfFpgas;\n}\n\nint libztex_selectFpga(struct libztex_device *ztex)\n{\n\tint cnt, fpgacnt = libztex_numberOfFpgas(ztex->root);\n\tint16_t number = ztex->fpgaNum;\n\n\tif (number < 0 || number >= fpgacnt) {\n\t\tapplog(LOG_WARNING, \"%s: Trying to select wrong fpga (%d in %d)\", ztex->repr, number, fpgacnt);\n\t\treturn 1;\n\t}\n\tif (ztex->root->selectedFpga != number && libztex_checkCapability(ztex->root, CAPABILITY_MULTI_FPGA)) {\n\t\tcnt = libusb_control_transfer(ztex->root->hndl, 0x40, 0x51, (uint16_t)number, 0, NULL, 0, 500);\n\t\tif (unlikely(cnt < 0)) {\n\t\t\tapplog(LOG_ERR, \"Ztex check device: Failed to set fpga with err %d\", cnt);\n\t\t\tztex->root->selectedFpga = -1;\n\t\t\treturn cnt;\n\t\t}\n\t\tztex->root->selectedFpga = number;\n\t}\n\treturn 0;\n}\n\nint libztex_setFreq(struct libztex_device *ztex, uint16_t freq)\n{\n\tint cnt;\n\tuint16_t oldfreq = ztex->freqM;\n\n\tif (freq > ztex->freqMaxM)\n\t\tfreq = ztex->freqMaxM;\n\n\tcnt = libusb_control_transfer(ztex->hndl, 0x40, 0x83, freq, 0, NULL, 0, 500);\n\tif (unlikely(cnt < 0)) {\n\t\tapplog(LOG_ERR, \"Ztex check device: Failed to set frequency with err %d\", cnt);\n\t\treturn cnt;\n\t}\n\tztex->freqM = freq;\n\tif (oldfreq > ztex->freqMaxM) \n\t\tapplog(LOG_WARNING, \"%s: Frequency set to %0.1f MHz\",\n\t\t       ztex->repr, ztex->freqM1 * (ztex->freqM + 1));\n\telse\n\t\tapplog(LOG_WARNING, \"%s: Frequency change from %0.1f to %0.1f MHz\",\n\t\t       ztex->repr, ztex->freqM1 * (oldfreq + 1), ztex->freqM1 * (ztex->freqM + 1));\n\n\treturn 0;\n}\n\nint libztex_resetFpga(struct libztex_device *ztex)\n{\n\treturn libusb_control_transfer(ztex->hndl, 0x40, 0x31, 0, 0, NULL, 0, 1000);\n}\n\nint libztex_suspend(struct libztex_device *ztex)\n{\n\tif (ztex->suspendSupported) {\n\t\treturn libusb_control_transfer(ztex->hndl, 0x40, 0x84, 0, 0, NULL, 0, 1000);\n\t} else {\n\t\treturn 0;\n\t}\n}\n\nint libztex_prepare_device(struct libusb_device *dev, struct libztex_device** ztex)\n{\n\tstruct libztex_device *newdev = *ztex;\n\tint i, cnt, err;\n\tunsigned char buf[64];\n\n\terr = libusb_open(dev, &newdev->hndl);\n\tif (err != LIBUSB_SUCCESS) {\n\t\tapplog(LOG_ERR, \"%s: Can not open ZTEX device: %d\", __func__, err);\n\t\treturn CHECK_ERROR;\n\t}\n\n\terr = libusb_get_device_descriptor(dev, &newdev->descriptor);\n\tif (unlikely(err != 0)) {\n\t\tapplog(LOG_ERR, \"Ztex check device: Failed to open read descriptor with error %d\", err);\n\t\treturn CHECK_ERROR;\n\t}\n\n\tcnt = libztex_get_string_descriptor_ascii(newdev->hndl, newdev->descriptor.iSerialNumber, newdev->snString, sizeof(newdev->snString));\n\tif (unlikely(cnt < 0)) {\n\t\tapplog(LOG_ERR, \"Ztex check device: Failed to read device snString with err %d\", cnt);\n\t\treturn cnt;\n\t}\n\n\tcnt = libusb_control_transfer(newdev->hndl, 0xc0, 0x22, 0, 0, buf, 40, 500);\n\tif (unlikely(cnt < 0)) {\n\t\tapplog(LOG_ERR, \"Ztex check device: Failed to read ztex descriptor with err %d\", cnt);\n\t\treturn cnt;\n\t}\n\n\tif (buf[0] != 40 || buf[1] != 1 || buf[2] != 'Z' || buf[3] != 'T' || buf[4] != 'E' || buf[5] != 'X') {\n\t\tapplog(LOG_ERR, \"Ztex check device: Error reading ztex descriptor\");\n\t\treturn 2;\n\t}\n\n\tnewdev->productId[0] = buf[6];\n\tnewdev->productId[1] = buf[7];\n\tnewdev->productId[2] = buf[8];\n\tnewdev->productId[3] = buf[9];\n\tnewdev->fwVersion = buf[10];\n\tnewdev->interfaceVersion = buf[11];\n\tnewdev->interfaceCapabilities[0] = buf[12];\n\tnewdev->interfaceCapabilities[1] = buf[13];\n\tnewdev->interfaceCapabilities[2] = buf[14];\n\tnewdev->interfaceCapabilities[3] = buf[15];\n\tnewdev->interfaceCapabilities[4] = buf[16];\n\tnewdev->interfaceCapabilities[5] = buf[17];\n\tnewdev->moduleReserved[0] = buf[18];\n\tnewdev->moduleReserved[1] = buf[19];\n\tnewdev->moduleReserved[2] = buf[20];\n\tnewdev->moduleReserved[3] = buf[21];\n\tnewdev->moduleReserved[4] = buf[22];\n\tnewdev->moduleReserved[5] = buf[23];\n\tnewdev->moduleReserved[6] = buf[24];\n\tnewdev->moduleReserved[7] = buf[25];\n\tnewdev->moduleReserved[8] = buf[26];\n\tnewdev->moduleReserved[9] = buf[27];\n\tnewdev->moduleReserved[10] = buf[28];\n\tnewdev->moduleReserved[11] = buf[29];\n\n\tcnt = libusb_control_transfer(newdev->hndl, 0xc0, 0x82, 0, 0, buf, 64, 500);\n\tif (unlikely(cnt < 0)) {\n\t\tapplog(LOG_ERR, \"Ztex check device: Failed to read ztex descriptor with err %d\", cnt);\n\t\treturn cnt;\n\t}\n\n\tif (unlikely(buf[0] != 5)) {\n\t\tif (unlikely(buf[0] != 2 && buf[0] != 4)) {\n\t\t\tapplog(LOG_ERR, \"Invalid BTCMiner descriptor version. Firmware must be updated (%d).\", buf[0]);\n\t\t\treturn 3;\n\t\t}\n\t\tapplog(LOG_WARNING, \"Firmware out of date (%d).\", buf[0]);\n\t}\n\n\ti = buf[0] > 4? 11: (buf[0] > 2? 10: 8);\n\n\twhile (cnt < 64 && buf[cnt] != 0)\n\t\tcnt++;\n\tif (cnt < i + 1) {\n\t\tapplog(LOG_ERR, \"Invalid bitstream file name .\");\n\t\treturn 4;\n\t}\n\n\tnewdev->bitFileName = malloc(sizeof(char) * (cnt + 1));\n\tmemcpy(newdev->bitFileName, &buf[i], cnt);\n\tnewdev->bitFileName[cnt] = 0;\t\n\n\t// For Blake OVERRIDE firmware configuration of clock speeds since we run slightly slower\n\t// NB These are set in ztex_ufm1_15y1.c, with units of 4MHz\n\t// Min clock is hardcoded as 25 (100MHz) in the firmware, max is freqMaxM = 62 (248MHz), default freqM = 50 (200MHz)\n\t// NB option zetx_clock will override freqM and freqMaxM\n\t\n\tnewdev->numNonces = buf[1] + 1;\n\tnewdev->offsNonces = ((buf[2] & 255) | ((buf[3] & 255) << 8)) - 10000;\n\tnewdev->freqM1 = ((buf[4] & 255) | ((buf[5] & 255) << 8) ) * 0.01;\n\n\t// ORIGINAL\n\t// newdev->freqMaxM = (buf[7] & 255);\n\t// newdev->freqM = (buf[6] & 255);\n\n#if 0\t// FIXED CLOCK\n\tnewdev->freqMaxM = 44;\t\t\t\t\t// OVERRIDE set max 180MHz\n\t// newdev->freqMaxM = 46;\t\t\t\t// OVERRIDE set max 188MHz\n\t// newdev->freqMaxM = 48;\t\t\t\t// OVERRIDE set max 196MHz\n\t// newdev->freqMaxM = 50;\t\t\t\t// OVERRIDE set max 204MHz\n\t// newdev->freqMaxM = 51;\t\t\t\t// OVERRIDE set max 208MHz\n\t// newdev->freqMaxM = 52;\t\t\t\t// OVERRIDE set max 212MHz\n\t// newdev->freqMaxM = 54;\t\t\t\t// OVERRIDE set max 220MHz\n\tnewdev->freqM = newdev->freqMaxM;\t\t// Initial is same as max\n#endif\n\n#if 1\t// PRODUCTION\n\tnewdev->freqMaxM = 48;\t\t\t\t\t// OVERRIDE set max 196 MHz\n\tnewdev->freqM = 30;\t\t\t\t\t\t// OVERRIDE set initial 124 MHz\n#endif\n\n\tnewdev->freqMDefault = newdev->freqM;\n\tnewdev->suspendSupported = (buf[0] == 5);\n\tnewdev->hashesPerClock = buf[0] > 2? (((buf[8] & 255) | ((buf[9] & 255) << 8)) + 1) / 128.0: 1.0;\n\tnewdev->extraSolutions = buf[0] > 4? buf[10]: 0;\n\t\t\n\tapplog(LOG_DEBUG, \"PID: %d numNonces: %d offsNonces: %d freqM1: %f freqMaxM: %d freqM: %d suspendSupported: %s hashesPerClock: %f extraSolutions: %d\",\n\t                 buf[0], newdev->numNonces, newdev->offsNonces, newdev->freqM1, newdev->freqMaxM, newdev->freqM, newdev->suspendSupported ? \"T\": \"F\", \n\t                 newdev->hashesPerClock, newdev->extraSolutions);\n\n\tif (buf[0] < 4) {\n\t\tif (strncmp(newdev->bitFileName, \"ztex_ufm1_15b\", 13) != 0)\n\t\t\tnewdev->hashesPerClock = 0.5;\n\t\tapplog(LOG_WARNING, \"HASHES_PER_CLOCK not defined, assuming %0.2f\", newdev->hashesPerClock);\n\t}\n\n\tfor (cnt=0; cnt < 255; cnt++) {\n\t\tnewdev->errorCount[cnt] = 0;\n\t\tnewdev->errorWeight[cnt] = 0;\n\t\tnewdev->errorRate[cnt] = 0;\n\t\tnewdev->maxErrorRate[cnt] = 0;\n\t}\n\n\t// fake that the last round found something valid\n\tnewdev->nonceCheckValid = 1;\n\n\tnewdev->usbbus = libusb_get_bus_number(dev);\n\tnewdev->usbaddress = libusb_get_device_address(dev);\n\tsprintf(newdev->repr, \"ZTEX %s-1\", newdev->snString);\n\treturn 0;\n}\n\nvoid libztex_destroy_device(struct libztex_device* ztex)\n{\n\tif (ztex->hndl != NULL) {\n\t\tlibusb_close(ztex->hndl);\n\t\tztex->hndl = NULL;\n\t}\n\tif (ztex->bitFileName != NULL) {\n\t\tfree(ztex->bitFileName);\n\t\tztex->bitFileName = NULL;\n\t}\n\tfree(ztex);\n}\n\nint libztex_scanDevices(struct libztex_dev_list*** devs_p)\n{\n\tint usbdevices[LIBZTEX_MAX_DESCRIPTORS];\n\tstruct libztex_dev_list **devs = NULL;\n\tstruct libztex_device *ztex = NULL;\n\tint found, max_found = 0, pos = 0, err, rescan, ret = 0;\n\tlibusb_device **list = NULL;\n\tssize_t cnt, i;\n\n\tdo {\n\t\tcnt = libusb_get_device_list(NULL, &list);\n\t\tif (unlikely(cnt < 0)) {\n\t\t\tapplog(LOG_ERR, \"Ztex scan devices: Failed to list usb devices with err %zd\", cnt);\n\t\t\tgoto done;\n\t\t}\n\n\t\tfor (found = rescan = i = 0; i < cnt; i++) {\n\t\t\terr = libztex_checkDevice(list[i]);\n\t\t\tswitch (err) {\n\t\t\tcase CHECK_ERROR:\n\t\t\t\tapplog(LOG_ERR, \"Ztex: Can not check device: %d\", err);\n\t\t\t\tcontinue;\n\t\t\tcase CHECK_IS_NOT_ZTEX:\n\t\t\t\tcontinue;\n\t\t\tcase CHECK_OK:\n\t\t\t\t// Got one!\n\t\t\t\tusbdevices[found++] = i;\n\t\t\t\tbreak;\n\t\t\tcase CHECK_RESCAN:\n\t\t\t\trescan = 1;\n\t\t\t\tfound++;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (found < max_found)\n\t\t\trescan = 1;\n\t\telse if (found > max_found)\n\t\t\tmax_found = found;\n\n\t\tif (rescan)\n\t\t\tlibusb_free_device_list(list, 1);\n\t} while (rescan);\n\n\tif (0 == found)\n\t\tgoto done;\n\n\tdevs = malloc(sizeof(struct libztex_dev_list *) * found);\n\tif (devs == NULL) {\n\t\tapplog(LOG_ERR, \"Ztex scan devices: Failed to allocate memory\");\n\t\tgoto done;\n\t}\n\n\tfor (i = 0; i < found; i++) {\n\t\tif (!ztex) {\n\t\t\tztex = malloc(sizeof(*ztex));\n\t\t\tif (!ztex) {\n\t\t\t\tapplog(LOG_ERR, \"%s: Can not allocate memory for device struct: %s\", __func__, strerror(errno));\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t}\n\n\t\tztex->bitFileName = NULL;\n\t\tztex->numberOfFpgas = -1;\n\n\t\terr = libztex_prepare_device(list[usbdevices[i]], &ztex);\n\t\tif (unlikely(err != 0)) {\n\t\t\tapplog(LOG_ERR, \"prepare device: %d\", err);\n\t\t\tlibztex_destroy_device(ztex);\n\t\t\tztex = NULL;\n\t\t\tcontinue;\n\t\t}\n\n\t\tdevs[pos] = malloc(sizeof(struct libztex_dev_list));\n\t\tif (NULL == devs[pos]) {\n\t\t\tapplog(LOG_ERR, \"%s: Can not allocate memory for device: %s\", __func__, strerror(errno));\n\t\t\tlibztex_destroy_device(ztex);\n\t\t\tztex = NULL;\n\t\t\tcontinue;\n\t\t}\n\n\t\tdevs[pos]->dev = ztex;\n\t\tztex = NULL;\n\t\tdevs[pos]->next = NULL;\n\t\tif (pos > 0)\n\t\t\tdevs[pos - 1]->next = devs[pos];\n\t\tpos++;\n\t}\n\n\tret = pos;\n\ndone:\n\tif (ret > 0)\n\t\t*devs_p = devs;\n\telse if (devs)\n\t\tfree(devs);\n\tif (list)\n\t\tlibusb_free_device_list(list, 1);\n\treturn ret;\n}\n\nint libztex_sendHashData(struct libztex_device *ztex, unsigned char *sendbuf, int numbytes)\n{\n\tint cnt = 0, ret, len;\n\n\tif (ztex == NULL || ztex->hndl == NULL)\n\t\treturn 0;\n\t// ret = 44; len = 0;\n\tret = numbytes; len = 0;\t\t// KRAMBLE\n\twhile (ret > 0) {\n\t\tcnt = libusb_control_transfer(ztex->hndl, 0x40, 0x80, 0, 0, sendbuf + len, ret, 1000);\n\t\tif (cnt >= 0) {\n\t\t\tret -= cnt;\n\t\t\tlen += cnt;\n\t\t} else\n\t\t\tbreak;\n\t}\n\tif (unlikely(cnt < 0))\n\t\tapplog(LOG_ERR, \"%s: Failed sendHashData with err %d\", ztex->repr, cnt);\n\n\treturn cnt;\n}\n\nint libztex_readHashData(struct libztex_device *ztex, struct libztex_hash_data nonces[])\n{\n\tint bufsize = 12 + ztex->extraSolutions * 4;\n\tint cnt = 0, i, j, ret, len;\n\tunsigned char *rbuf;\n\n\tif (ztex->hndl == NULL)\n\t\treturn 0;\n\n\trbuf = malloc(sizeof(unsigned char) * (ztex->numNonces * bufsize));\n\tif (rbuf == NULL) {\n\t\tapplog(LOG_ERR, \"%s: Failed to allocate memory for reading nonces\", ztex->repr);\n\t\treturn 0;\n\t}\n\tret = bufsize * ztex->numNonces; len = 0;\n\twhile (ret > 0) {\n\t\tcnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x81, 0, 0, rbuf + len, ret, 1000);\n\t\tif (cnt >= 0) {\n\t\t\tret -= cnt;\n\t\t\tlen += cnt;\n\t\t} else\n\t\t\tbreak;\n\t}\n\n\tif (unlikely(cnt < 0)) {\n\t\tapplog(LOG_ERR, \"%s: Failed readHashData with err %d\", ztex->repr, cnt);\n\t\tfree(rbuf);\n\t\treturn cnt;\n\t}\n\n\tfor (i=0; i<ztex->numNonces; i++) {\n\t\tmemcpy((char*)&nonces[i].goldenNonce[0], &rbuf[i*bufsize], 4);\n\t\tnonces[i].goldenNonce[0] -= ztex->offsNonces;\n\t\t//applog(LOG_DEBUG, \"W %d:0 %0.8x\", i, nonces[i].goldenNonce[0]);\n\n\t\tmemcpy((char*)&nonces[i].nonce, &rbuf[(i*bufsize)+4], 4);\n\t\tmemcpy((char*)&nonces[i].hash7, &rbuf[(i*bufsize)+8], 4);\n\n\t\tnonces[i].nonce = htole32(nonces[i].nonce);\n\t\tnonces[i].hash7 = htole32(nonces[i].hash7);\n\n\t\tnonces[i].nonce -= ztex->offsNonces;\n\n\t\tfor (j=0; j<ztex->extraSolutions; j++) {\n\t\t\tmemcpy((char*)&nonces[i].goldenNonce[j+1], &rbuf[(i*bufsize)+12+(j*4)], 4);\n\t\t\tnonces[i].goldenNonce[j+1] = htole32(nonces[i].goldenNonce[j+1]);\n\t\t\tnonces[i].goldenNonce[j+1] -= ztex->offsNonces;\n\t\t\t//applog(LOG_DEBUG, \"W %d:%d %0.8x\", i, j+1, nonces[i].goldenNonce[j+1]);\n\t\t}\n\t}\n\n\tfree(rbuf);\n\treturn cnt;\n}\n\nvoid libztex_freeDevList(struct libztex_dev_list **devs)\n{\n\tbool done = false;\n\tssize_t cnt = 0;\n\n\twhile (!done) {\n\t\tif (devs[cnt]->next == NULL)\n\t\t\tdone = true;\n\t\tfree(devs[cnt++]);\n\t}\n\tfree(devs);\n}\n\n"
  },
  {
    "path": "experimental/Ztex-1-15y/cgminer-3.1.1/libztex.h",
    "content": "/**\n *   libztex.h - headers for Ztex 1.15x fpga board support library\n *\n *   Copyright (c) 2012 nelisky.btc@gmail.com\n *\n *   This work is based upon the Java SDK provided by ztex which is\n *   Copyright (C) 2009-2011 ZTEX GmbH.\n *   http://www.ztex.de\n *\n *   This program is free software; you can redistribute it and/or modify\n *   it under the terms of the GNU General Public License version 2 as\n *   published by the Free Software Foundation.\n *\n *   This program is distributed in the hope that it will be useful, but\n *   WITHOUT ANY WARRANTY; without even the implied warranty of\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n *   General Public License for more details.\n *\n *   You should have received a copy of the GNU General Public License\n *   along with this program; if not, see http://www.gnu.org/licenses/.\n**/\n#ifndef __LIBZTEX_H__\n#define __LIBZTEX_H__\n\n#include <libusb.h>\n\n#define LIBZTEX_MAX_DESCRIPTORS 512\n#define LIBZTEX_SNSTRING_LEN 10\n\n#define LIBZTEX_IDVENDOR 0x221A\n#define LIBZTEX_IDPRODUCT 0x0100\n\n#define LIBZTEX_MAXMAXERRORRATE 0.05\n#define LIBZTEX_ERRORHYSTERESIS 0.1\n#define LIBZTEX_OVERHEATTHRESHOLD 0.4\n\nstruct libztex_fpgastate {\n\tbool fpgaConfigured;\n\tunsigned char fpgaChecksum;\n\tuint16_t fpgaBytes;\n\tunsigned char fpgaInitB;\n\tunsigned char fpgaFlashResult;\n\tbool fpgaFlashBitSwap;\n};\n\nstruct libztex_device {\n\tpthread_mutex_t\tmutex;\n\tstruct libztex_device *root;\n\tint16_t fpgaNum;\n\tstruct libusb_device_descriptor descriptor;\n\tlibusb_device_handle *hndl; \n\tunsigned char usbbus;\n\tunsigned char usbaddress;\n\tunsigned char snString[LIBZTEX_SNSTRING_LEN+1];\n\tunsigned char productId[4];\n\tunsigned char fwVersion;\n\tunsigned char interfaceVersion;\n\tunsigned char interfaceCapabilities[6];\n\tunsigned char moduleReserved[12];\n\tuint8_t numNonces;\n\tuint16_t offsNonces;\n\tdouble freqM1;\t\n\tuint8_t freqM;\n\tuint8_t freqMaxM;\n\tuint8_t freqMDefault;\n\tchar* bitFileName;\n\tbool suspendSupported;\n\tdouble hashesPerClock;\n\tuint8_t extraSolutions;\n\n\tdouble errorCount[256];\n\tdouble errorWeight[256];\n\tdouble errorRate[256];\n\tdouble maxErrorRate[256];\n\tint lockClock;\t\t\t\t// KRAMBLE\n\n\tint16_t nonceCheckValid;\n\n\tint16_t numberOfFpgas;\n\tint selectedFpga;\n\tbool parallelConfigSupport;\n\t\n\tchar repr[20];\n};\n\nstruct libztex_dev_list { \n\tstruct libztex_device *dev;\n\tstruct libztex_dev_list *next;\n};\n\nstruct libztex_hash_data {\n\tuint32_t goldenNonce[2];\n\tuint32_t nonce;\n\tuint32_t hash7;\n};\n\nextern int libztex_scanDevices (struct libztex_dev_list ***devs);\nextern void libztex_freeDevList (struct libztex_dev_list **devs);\nextern int libztex_prepare_device (struct libusb_device *dev, struct libztex_device** ztex);\nextern void libztex_destroy_device (struct libztex_device* ztex);\nextern int libztex_configureFpga (struct libztex_device *dev);\nextern int libztex_setFreq (struct libztex_device *ztex, uint16_t freq);\nextern int libztex_sendHashData (struct libztex_device *ztex, unsigned char *sendbuf, int numbytes);\t// KRAMBLE\nextern int libztex_readHashData (struct libztex_device *ztex, struct libztex_hash_data nonces[]);\nextern int libztex_resetFpga (struct libztex_device *ztex);\nextern int libztex_selectFpga(struct libztex_device *ztex);\nextern int libztex_numberOfFpgas(struct libztex_device *ztex);\n\n#endif /* __LIBZTEX_H__ */\n"
  },
  {
    "path": "experimental/Ztex-1-15y/cgminer-3.1.1/miner.h",
    "content": "#ifndef __MINER_H__\n#define __MINER_H__\n\n#include \"config.h\"\n\n#include <stdbool.h>\n#include <stdint.h>\n#include <sys/time.h>\n#include <pthread.h>\n#include <jansson.h>\n#include <curl/curl.h>\n#include \"elist.h\"\n#include \"uthash.h\"\n#include \"logging.h\"\n#include \"util.h\"\n#include <sys/types.h>\n#ifndef WIN32\n# include <sys/socket.h>\n# include <netdb.h>\n#endif\n\n#ifdef HAVE_OPENCL\n#ifdef __APPLE_CC__\n#include <OpenCL/opencl.h>\n#else\n#include <CL/cl.h>\n#endif\n#endif /* HAVE_OPENCL */\n\n#ifdef STDC_HEADERS\n# include <stdlib.h>\n# include <stddef.h>\n#else\n# ifdef HAVE_STDLIB_H\n#  include <stdlib.h>\n# endif\n#endif\n#ifdef HAVE_ALLOCA_H\n# include <alloca.h>\n#elif defined __GNUC__\n# ifndef WIN32\n#  define alloca __builtin_alloca\n# else\n#  include <malloc.h>\n# endif\n#elif defined _AIX\n# define alloca __alloca\n#elif defined _MSC_VER\n# include <malloc.h>\n# define alloca _alloca\n#else\n# ifndef HAVE_ALLOCA\n#  ifdef  __cplusplus\nextern \"C\"\n#  endif\nvoid *alloca (size_t);\n# endif\n#endif\n\n#ifdef __MINGW32__\n#include <windows.h>\n#include <io.h>\nstatic inline int fsync (int fd)\n{\n\treturn (FlushFileBuffers ((HANDLE) _get_osfhandle (fd))) ? 0 : -1;\n}\n\n#ifndef EWOULDBLOCK\n# define EWOULDBLOCK EAGAIN\n#endif\n\n#ifndef MSG_DONTWAIT\n# define MSG_DONTWAIT 0x1000000\n#endif\n#endif /* __MINGW32__ */\n\n#if defined (__linux)\n #ifndef LINUX\n  #define LINUX\n #endif\n#endif\n\n#ifdef WIN32\n  #ifndef timersub\n    #define timersub(a, b, result)                     \\\n    do {                                               \\\n      (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;    \\\n      (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \\\n      if ((result)->tv_usec < 0) {                     \\\n        --(result)->tv_sec;                            \\\n        (result)->tv_usec += 1000000;                  \\\n      }                                                \\\n    } while (0)\n  #endif\n #ifndef timeradd\n # define timeradd(a, b, result)\t\t\t      \\\n   do {\t\t\t\t\t\t\t      \\\n    (result)->tv_sec = (a)->tv_sec + (b)->tv_sec;\t      \\\n    (result)->tv_usec = (a)->tv_usec + (b)->tv_usec;\t      \\\n    if ((result)->tv_usec >= 1000000)\t\t\t      \\\n      {\t\t\t\t\t\t\t      \\\n\t++(result)->tv_sec;\t\t\t\t      \\\n\t(result)->tv_usec -= 1000000;\t\t\t      \\\n      }\t\t\t\t\t\t\t      \\\n   } while (0)\n #endif\n#endif\n\n\n#ifdef HAVE_ADL\n #include \"ADL_SDK/adl_sdk.h\"\n#endif\n\n#ifdef HAVE_LIBUSB\n  #include <libusb.h>\n#endif\n\n#ifdef USE_ZTEX\n  #include \"libztex.h\"\n#endif\n\n#ifdef USE_USBUTILS\n  #include \"usbutils.h\"\n#endif\n\n#if (!defined(WIN32) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \\\n    || (defined(WIN32) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))\n#ifndef bswap_16\n #define bswap_16 __builtin_bswap16\n #define bswap_32 __builtin_bswap32\n #define bswap_64 __builtin_bswap64\n#endif\n#else\n#if HAVE_BYTESWAP_H\n#include <byteswap.h>\n#elif defined(USE_SYS_ENDIAN_H)\n#include <sys/endian.h>\n#elif defined(__APPLE__)\n#include <libkern/OSByteOrder.h>\n#define bswap_16 OSSwapInt16\n#define bswap_32 OSSwapInt32\n#define bswap_64 OSSwapInt64\n#else\n#define\tbswap_16(value)  \\\n \t((((value) & 0xff) << 8) | ((value) >> 8))\n\n#define\tbswap_32(value)\t\\\n \t(((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \\\n \t(uint32_t)bswap_16((uint16_t)((value) >> 16)))\n\n#define\tbswap_64(value)\t\\\n \t(((uint64_t)bswap_32((uint32_t)((value) & 0xffffffff)) \\\n \t    << 32) | \\\n \t(uint64_t)bswap_32((uint32_t)((value) >> 32)))\n#endif\n#endif /* !defined(__GLXBYTEORDER_H__) */\n\n/* This assumes htobe32 is a macro in endian.h, and if it doesn't exist, then\n * htobe64 also won't exist */\n#ifndef htobe32\n# if __BYTE_ORDER == __LITTLE_ENDIAN\n#  define htole16(x) (x)\n#  define htole32(x) (x)\n#  define le32toh(x) (x)\n#  define be32toh(x) bswap_32(x)\n#  define be64toh(x) bswap_64(x)\n#  define htobe32(x) bswap_32(x)\n#  define htobe64(x) bswap_64(x)\n# elif __BYTE_ORDER == __BIG_ENDIAN\n#  define htole16(x) bswap_16(x)\n#  define htole32(x) bswap_32(x)\n#  define le32toh(x) bswap_32(x)\n#  define be32toh(x) (x)\n#  define be64toh(x) (x)\n#  define htobe32(x) (x)\n#  define htobe64(x) (x)\n#else\n#error UNKNOWN BYTE ORDER\n#endif\n#endif\n\n#undef unlikely\n#undef likely\n#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)\n#define unlikely(expr) (__builtin_expect(!!(expr), 0))\n#define likely(expr) (__builtin_expect(!!(expr), 1))\n#else\n#define unlikely(expr) (expr)\n#define likely(expr) (expr)\n#endif\n#define __maybe_unused\t\t__attribute__((unused))\n\n#define uninitialised_var(x) x = x\n\n#if defined(__i386__)\n#define WANT_CRYPTOPP_ASM32\n#endif\n\n#ifndef ARRAY_SIZE\n#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))\n#endif\n\n#ifdef MIPSEB\n#ifndef roundl\n#define roundl(x)   (long double)((long long)((x==0)?0.0:((x)+((x)>0)?0.5:-0.5)))\n#endif\n#endif\n\n#define MIN(x, y)\t((x) > (y) ? (y) : (x))\n#define MAX(x, y)\t((x) > (y) ? (x) : (y))\n\nenum drv_driver {\n\tDRIVER_OPENCL = 0,\n\tDRIVER_ICARUS,\n\tDRIVER_BITFORCE,\n\tDRIVER_MODMINER,\n\tDRIVER_ZTEX,\n\tDRIVER_BFLSC,\n\tDRIVER_AVALON,\n\tDRIVER_MAX\n};\n\nenum alive {\n\tLIFE_WELL,\n\tLIFE_SICK,\n\tLIFE_DEAD,\n\tLIFE_NOSTART,\n\tLIFE_INIT,\n};\n\n\nenum pool_strategy {\n\tPOOL_FAILOVER,\n\tPOOL_ROUNDROBIN,\n\tPOOL_ROTATE,\n\tPOOL_LOADBALANCE,\n\tPOOL_BALANCE,\n};\n\n#define TOP_STRATEGY (POOL_BALANCE)\n\nstruct strategies {\n\tconst char *s;\n};\n\nstruct cgpu_info;\n\n#ifdef HAVE_ADL\nstruct gpu_adl {\n\tADLTemperature lpTemperature;\n\tint iAdapterIndex;\n\tint lpAdapterID;\n\tint iBusNumber;\n\tchar strAdapterName[256];\n\n\tADLPMActivity lpActivity;\n\tADLODParameters lpOdParameters;\n\tADLODPerformanceLevels *DefPerfLev;\n\tADLFanSpeedInfo lpFanSpeedInfo;\n\tADLFanSpeedValue lpFanSpeedValue;\n\tADLFanSpeedValue DefFanSpeedValue;\n\n\tint iEngineClock;\n\tint iMemoryClock;\n\tint iVddc;\n\tint iPercentage;\n\n\tbool autofan;\n\tbool autoengine;\n\tbool managed; /* Were the values ever changed on this card */\n\n\tint lastengine;\n\tint lasttemp;\n\tint targetfan;\n\tint targettemp;\n\tint overtemp;\n\tint minspeed;\n\tint maxspeed;\n\n\tint gpu;\n\tbool has_fanspeed;\n\tstruct gpu_adl *twin;\n};\n#endif\n\nextern void blank_get_statline_before(char *buf, struct cgpu_info __maybe_unused *cgpu);\n\nstruct api_data;\nstruct thr_info;\nstruct work;\n\nstruct device_drv {\n\tenum drv_driver drv_id;\n\n\tchar *dname;\n\tchar *name;\n\n\t// DRV-global functions\n\tvoid (*drv_detect)();\n\n\t// Device-specific functions\n\tvoid (*reinit_device)(struct cgpu_info *);\n\tvoid (*get_statline_before)(char *, struct cgpu_info *);\n\tvoid (*get_statline)(char *, struct cgpu_info *);\n\tstruct api_data *(*get_api_stats)(struct cgpu_info *);\n\tbool (*get_stats)(struct cgpu_info *);\n\tvoid (*identify_device)(struct cgpu_info *); // e.g. to flash a led\n\tchar *(*set_device)(struct cgpu_info *, char *option, char *setting, char *replybuf);\n\n\t// Thread-specific functions\n\tbool (*thread_prepare)(struct thr_info *);\n\tuint64_t (*can_limit_work)(struct thr_info *);\n\tbool (*thread_init)(struct thr_info *);\n\tbool (*prepare_work)(struct thr_info *, struct work *);\n\n\t/* Which hash work loop this driver uses. */\n\tvoid (*hash_work)(struct thr_info *);\n\t/* Two variants depending on whether the device divides work up into\n\t * small pieces or works with whole work items and may or may not have\n\t * a queue of its own. */\n\tint64_t (*scanhash)(struct thr_info *, struct work *, int64_t);\n\tint64_t (*scanwork)(struct thr_info *);\n\n\t/* Used to extract work from the hash table of queued work and tell\n\t * the main loop that it should not add any further work to the table.\n\t */\n\tbool (*queue_full)(struct cgpu_info *);\n\tvoid (*flush_work)(struct cgpu_info *);\n\n\tvoid (*hw_error)(struct thr_info *);\n\tvoid (*thread_shutdown)(struct thr_info *);\n\tvoid (*thread_enable)(struct thr_info *);\n\n\t// Does it need to be free()d?\n\tbool copy;\n\n\t/* Highest target diff the device supports */\n\tdouble max_diff;\n\tdouble working_diff;\n};\n\nextern struct device_drv *copy_drv(struct device_drv*);\n\nenum dev_enable {\n\tDEV_ENABLED,\n\tDEV_DISABLED,\n\tDEV_RECOVER,\n};\n\nenum cl_kernels {\n\tKL_NONE,\n\tKL_POCLBM,\n\tKL_PHATK,\n\tKL_DIAKGCN,\n\tKL_DIABLO,\n\tKL_SCRYPT,\n};\n\nenum dev_reason {\n\tREASON_THREAD_FAIL_INIT,\n\tREASON_THREAD_ZERO_HASH,\n\tREASON_THREAD_FAIL_QUEUE,\n\tREASON_DEV_SICK_IDLE_60,\n\tREASON_DEV_DEAD_IDLE_600,\n\tREASON_DEV_NOSTART,\n\tREASON_DEV_OVER_HEAT,\n\tREASON_DEV_THERMAL_CUTOFF,\n\tREASON_DEV_COMMS_ERROR,\n\tREASON_DEV_THROTTLE,\n};\n\n#define REASON_NONE\t\t\t\"None\"\n#define REASON_THREAD_FAIL_INIT_STR\t\"Thread failed to init\"\n#define REASON_THREAD_ZERO_HASH_STR\t\"Thread got zero hashes\"\n#define REASON_THREAD_FAIL_QUEUE_STR\t\"Thread failed to queue work\"\n#define REASON_DEV_SICK_IDLE_60_STR\t\"Device idle for 60s\"\n#define REASON_DEV_DEAD_IDLE_600_STR\t\"Device dead - idle for 600s\"\n#define REASON_DEV_NOSTART_STR\t\t\"Device failed to start\"\n#define REASON_DEV_OVER_HEAT_STR\t\"Device over heated\"\n#define REASON_DEV_THERMAL_CUTOFF_STR\t\"Device reached thermal cutoff\"\n#define REASON_DEV_COMMS_ERROR_STR\t\"Device comms error\"\n#define REASON_DEV_THROTTLE_STR\t\t\"Device throttle\"\n#define REASON_UNKNOWN_STR\t\t\"Unknown reason - code bug\"\n\n#define MIN_SEC_UNSET 99999999\n\nstruct cgminer_stats {\n\tuint32_t getwork_calls;\n\tstruct timeval getwork_wait;\n\tstruct timeval getwork_wait_max;\n\tstruct timeval getwork_wait_min;\n};\n\n// Just the actual network getworks to the pool\nstruct cgminer_pool_stats {\n\tuint32_t getwork_calls;\n\tuint32_t getwork_attempts;\n\tstruct timeval getwork_wait;\n\tstruct timeval getwork_wait_max;\n\tstruct timeval getwork_wait_min;\n\tdouble getwork_wait_rolling;\n\tbool hadrolltime;\n\tbool canroll;\n\tbool hadexpire;\n\tuint32_t rolltime;\n\tdouble min_diff;\n\tdouble max_diff;\n\tdouble last_diff;\n\tuint32_t min_diff_count;\n\tuint32_t max_diff_count;\n\tuint64_t times_sent;\n\tuint64_t bytes_sent;\n\tuint64_t net_bytes_sent;\n\tuint64_t times_received;\n\tuint64_t bytes_received;\n\tuint64_t net_bytes_received;\n};\n\nstruct cgpu_info {\n\tint cgminer_id;\n\tstruct device_drv *drv;\n\tint device_id;\n\tchar *name;\n\tchar *device_path;\n\tFILE *device_file;\n\tunion {\n#ifdef USE_ZTEX\n\t\tstruct libztex_device *device_ztex;\n#endif\n#ifdef USE_USBUTILS\n\t\tstruct cg_usb_device *usbdev;\n#endif\n#if defined(USE_ICARUS) || defined(USE_AVALON)\n\t\tint device_fd;\n#endif\n\t};\n#ifdef USE_AVALON\n\tstruct work **works;\n\tint work_array;\n\tint queued;\n\tint results;\n#endif\n#ifdef USE_USBUTILS\n\tstruct cg_usb_info usbinfo;\n#endif\n#ifdef USE_MODMINER\n\tchar fpgaid;\n\tunsigned char clock;\n\tpthread_mutex_t *modminer_mutex;\n#endif\n#ifdef USE_BITFORCE\n\tstruct timeval work_start_tv;\n\tunsigned int wait_ms;\n\tunsigned int sleep_ms;\n\tdouble avg_wait_f;\n\tunsigned int avg_wait_d;\n\tuint32_t nonces;\n\tbool nonce_range;\n\tbool polling;\n\tbool flash_led;\n#endif /* USE_BITFORCE */\n#if defined(USE_BITFORCE) || defined(USE_BFLSC)\n\tpthread_mutex_t device_mutex;\n#endif /* USE_BITFORCE || USE_BFLSC */\n\tenum dev_enable deven;\n\tint accepted;\n\tint rejected;\n\tint hw_errors;\n\tdouble rolling;\n\tdouble total_mhashes;\n\tdouble utility;\n\tenum alive status;\n\tchar init[40];\n\tstruct timeval last_message_tv;\n\n\tint threads;\n\tstruct thr_info **thr;\n\n\tint64_t max_hashes;\n\n\tconst char *kname;\n#ifdef HAVE_OPENCL\n\tbool mapped;\n\tint virtual_gpu;\n\tint virtual_adl;\n\tint intensity;\n\tbool dynamic;\n\n\tcl_uint vwidth;\n\tsize_t work_size;\n\tenum cl_kernels kernel;\n\tcl_ulong max_alloc;\n\n#ifdef USE_SCRYPT\n\tint opt_lg, lookup_gap;\n\tsize_t opt_tc, thread_concurrency;\n\tsize_t shaders;\n#endif\n\tstruct timeval tv_gpustart;\n\tint intervals;\n#endif\n\n\tbool new_work;\n\n\tfloat temp;\n\tint cutofftemp;\n\n#ifdef HAVE_ADL\n\tbool has_adl;\n\tstruct gpu_adl adl;\n\n\tint gpu_engine;\n\tint min_engine;\n\tint gpu_fan;\n\tint min_fan;\n\tint gpu_memclock;\n\tint gpu_memdiff;\n\tint gpu_powertune;\n\tfloat gpu_vddc;\n#endif\n\tint diff1;\n\tdouble diff_accepted;\n\tdouble diff_rejected;\n\tint last_share_pool;\n\ttime_t last_share_pool_time;\n\tdouble last_share_diff;\n\ttime_t last_device_valid_work;\n\n\ttime_t device_last_well;\n\ttime_t device_last_not_well;\n\tenum dev_reason device_not_well_reason;\n\tint thread_fail_init_count;\n\tint thread_zero_hash_count;\n\tint thread_fail_queue_count;\n\tint dev_sick_idle_60_count;\n\tint dev_dead_idle_600_count;\n\tint dev_nostart_count;\n\tint dev_over_heat_count;\t// It's a warning but worth knowing\n\tint dev_thermal_cutoff_count;\n\tint dev_comms_error_count;\n\tint dev_throttle_count;\n\n\tstruct cgminer_stats cgminer_stats;\n\n\tpthread_rwlock_t qlock;\n\tstruct work *queued_work;\n\tunsigned int queued_count;\n};\n\nextern bool add_cgpu(struct cgpu_info*);\n\nstruct thread_q {\n\tstruct list_head\tq;\n\n\tbool frozen;\n\n\tpthread_mutex_t\t\tmutex;\n\tpthread_cond_t\t\tcond;\n};\n\nstruct thr_info {\n\tint\t\tid;\n\tint\t\tdevice_thread;\n\tbool\t\tprimary_thread;\n\n\tpthread_t\tpth;\n\tstruct thread_q\t*q;\n\tstruct cgpu_info *cgpu;\n\tvoid *cgpu_data;\n\tstruct timeval last;\n\tstruct timeval sick;\n\n\tbool\tpause;\n\tbool\tgetwork;\n\tdouble\trolling;\n\n\tbool\twork_restart;\n};\n\nstruct string_elist {\n\tchar *string;\n\tbool free_me;\n\n\tstruct list_head list;\n};\n\nstatic inline void string_elist_add(const char *s, struct list_head *head)\n{\n\tstruct string_elist *n;\n\n\tn = calloc(1, sizeof(*n));\n\tn->string = strdup(s);\n\tn->free_me = true;\n\tlist_add_tail(&n->list, head);\n}\n\nstatic inline void string_elist_del(struct string_elist *item)\n{\n\tif (item->free_me)\n\t\tfree(item->string);\n\tlist_del(&item->list);\n}\n\n\nstatic inline uint32_t swab32(uint32_t v)\n{\n\treturn bswap_32(v);\n}\n\nstatic inline void swap256(void *dest_p, const void *src_p)\n{\n\tuint32_t *dest = dest_p;\n\tconst uint32_t *src = src_p;\n\n\tdest[0] = src[7];\n\tdest[1] = src[6];\n\tdest[2] = src[5];\n\tdest[3] = src[4];\n\tdest[4] = src[3];\n\tdest[5] = src[2];\n\tdest[6] = src[1];\n\tdest[7] = src[0];\n}\n\nstatic inline void swab256(void *dest_p, const void *src_p)\n{\n\tuint32_t *dest = dest_p;\n\tconst uint32_t *src = src_p;\n\n\tdest[0] = swab32(src[7]);\n\tdest[1] = swab32(src[6]);\n\tdest[2] = swab32(src[5]);\n\tdest[3] = swab32(src[4]);\n\tdest[4] = swab32(src[3]);\n\tdest[5] = swab32(src[2]);\n\tdest[6] = swab32(src[1]);\n\tdest[7] = swab32(src[0]);\n}\n\nstatic inline void flip32(void *dest_p, const void *src_p)\n{\n\tuint32_t *dest = dest_p;\n\tconst uint32_t *src = src_p;\n\tint i;\n\n\tfor (i = 0; i < 8; i++)\n\t\tdest[i] = swab32(src[i]);\n}\n\nstatic inline void flip64(void *dest_p, const void *src_p)\n{\n\tuint32_t *dest = dest_p;\n\tconst uint32_t *src = src_p;\n\tint i;\n\n\tfor (i = 0; i < 16; i++)\n\t\tdest[i] = swab32(src[i]);\n}\n\nstatic inline void flip80(void *dest_p, const void *src_p)\n{\n\tuint32_t *dest = dest_p;\n\tconst uint32_t *src = src_p;\n\tint i;\n\n\tfor (i = 0; i < 20; i++)\n\t\tdest[i] = swab32(src[i]);\n}\n\nstatic inline void flip128(void *dest_p, const void *src_p)\n{\n\tuint32_t *dest = dest_p;\n\tconst uint32_t *src = src_p;\n\tint i;\n\n\tfor (i = 0; i < 32; i++)\n\t\tdest[i] = swab32(src[i]);\n}\n\n/* For flipping to the correct endianness if necessary */\n#if defined(__BIG_ENDIAN__) || defined(MIPSEB)\nstatic inline void endian_flip32(void *dest_p, const void *src_p)\n{\n\tflip32(dest_p, src_p);\n}\n\nstatic inline void endian_flip128(void *dest_p, const void *src_p)\n{\n\tflip128(dest_p, src_p);\n}\n#else\nstatic inline void\nendian_flip32(void __maybe_unused *dest_p, const void __maybe_unused *src_p)\n{\n}\n\nstatic inline void\nendian_flip128(void __maybe_unused *dest_p, const void __maybe_unused *src_p)\n{\n}\n#endif\n\nextern void quit(int status, const char *format, ...);\n\nstatic inline void mutex_lock(pthread_mutex_t *lock)\n{\n\tif (unlikely(pthread_mutex_lock(lock)))\n\t\tquit(1, \"WTF MUTEX ERROR ON LOCK!\");\n}\n\nstatic inline void mutex_unlock(pthread_mutex_t *lock)\n{\n\tif (unlikely(pthread_mutex_unlock(lock)))\n\t\tquit(1, \"WTF MUTEX ERROR ON UNLOCK!\");\n}\n\nstatic inline int mutex_trylock(pthread_mutex_t *lock)\n{\n\treturn pthread_mutex_trylock(lock);\n}\n\nstatic inline void wr_lock(pthread_rwlock_t *lock)\n{\n\tif (unlikely(pthread_rwlock_wrlock(lock)))\n\t\tquit(1, \"WTF WRLOCK ERROR ON LOCK!\");\n}\n\nstatic inline void rd_lock(pthread_rwlock_t *lock)\n{\n\tif (unlikely(pthread_rwlock_rdlock(lock)))\n\t\tquit(1, \"WTF RDLOCK ERROR ON LOCK!\");\n}\n\nstatic inline void rw_unlock(pthread_rwlock_t *lock)\n{\n\tif (unlikely(pthread_rwlock_unlock(lock)))\n\t\tquit(1, \"WTF RWLOCK ERROR ON UNLOCK!\");\n}\n\nstatic inline void rd_unlock(pthread_rwlock_t *lock)\n{\n\trw_unlock(lock);\n}\n\nstatic inline void wr_unlock(pthread_rwlock_t *lock)\n{\n\trw_unlock(lock);\n}\n\nstatic inline void mutex_init(pthread_mutex_t *lock)\n{\n\tif (unlikely(pthread_mutex_init(lock, NULL)))\n\t\tquit(1, \"Failed to pthread_mutex_init\");\n}\n\nstatic inline void rwlock_init(pthread_rwlock_t *lock)\n{\n\tif (unlikely(pthread_rwlock_init(lock, NULL)))\n\t\tquit(1, \"Failed to pthread_rwlock_init\");\n}\n\n/* cgminer locks, a write biased variant of rwlocks */\nstruct cglock {\n\tpthread_mutex_t mutex;\n\tpthread_rwlock_t rwlock;\n};\n\ntypedef struct cglock cglock_t;\n\nstatic inline void cglock_init(cglock_t *lock)\n{\n\tmutex_init(&lock->mutex);\n\trwlock_init(&lock->rwlock);\n}\n\n/* Read lock variant of cglock */\nstatic inline void cg_rlock(cglock_t *lock)\n{\n\tmutex_lock(&lock->mutex);\n\trd_lock(&lock->rwlock);\n\tmutex_unlock(&lock->mutex);\n}\n\n/* Intermediate variant of cglock */\nstatic inline void cg_ilock(cglock_t *lock)\n{\n\tmutex_lock(&lock->mutex);\n}\n\n/* Upgrade intermediate variant to a write lock */\nstatic inline void cg_ulock(cglock_t *lock)\n{\n\twr_lock(&lock->rwlock);\n}\n\n/* Write lock variant of cglock */\nstatic inline void cg_wlock(cglock_t *lock)\n{\n\tmutex_lock(&lock->mutex);\n\twr_lock(&lock->rwlock);\n}\n\n/* Downgrade intermediate variant to a read lock */\nstatic inline void cg_dlock(cglock_t *lock)\n{\n\trd_lock(&lock->rwlock);\n\tmutex_unlock(&lock->mutex);\n}\n\nstatic inline void cg_runlock(cglock_t *lock)\n{\n\trd_unlock(&lock->rwlock);\n}\n\nstatic inline void cg_wunlock(cglock_t *lock)\n{\n\twr_unlock(&lock->rwlock);\n\tmutex_unlock(&lock->mutex);\n}\n\nstruct pool;\n\nextern bool opt_protocol;\nextern bool have_longpoll;\nextern char *opt_kernel_path;\nextern char *opt_socks_proxy;\nextern char *cgminer_path;\nextern bool opt_fail_only;\nextern bool opt_autofan;\nextern bool opt_autoengine;\nextern bool use_curses;\nextern char *opt_api_allow;\nextern char *opt_api_groups;\nextern char *opt_api_description;\nextern int opt_api_port;\nextern bool opt_api_listen;\nextern bool opt_api_network;\nextern bool opt_delaynet;\nextern bool opt_restart;\nextern char *opt_icarus_options;\nextern char *opt_icarus_timing;\nextern char *opt_cainsmore_clock;\t// KRAMBLE\nextern char *opt_ztex_clock;\t\t// KRAMBLE\nextern bool opt_worktime;\n#ifdef USE_AVALON\nextern char *opt_avalon_options;\n#endif\n#ifdef USE_USBUTILS\nextern char *opt_usb_select;\nextern int opt_usbdump;\nextern bool opt_usb_list_all;\n#endif\n#ifdef USE_BITFORCE\nextern bool opt_bfl_noncerange;\n#endif\nextern bool ping;\nextern int swork_id;\n\nextern pthread_rwlock_t netacc_lock;\n\nextern const uint32_t sha256_init_state[];\nextern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass,\n\t\t\t     const char *rpc_req, bool, bool, int *,\n\t\t\t     struct pool *pool, bool);\nextern const char *proxytype(curl_proxytype proxytype);\nextern char *get_proxy(char *url, struct pool *pool);\nextern char *bin2hex(const unsigned char *p, size_t len);\nextern bool hex2bin(unsigned char *p, const char *hexstr, size_t len);\n\ntypedef bool (*sha256_func)(struct thr_info*, const unsigned char *pmidstate,\n\tunsigned char *pdata,\n\tunsigned char *phash1, unsigned char *phash,\n\tconst unsigned char *ptarget,\n\tuint32_t max_nonce,\n\tuint32_t *last_nonce,\n\tuint32_t nonce);\n\nextern bool fulltest(const unsigned char *hash, const unsigned char *target);\n\nextern int opt_queue;\nextern int opt_scantime;\nextern int opt_expiry;\n\n#ifdef USE_USBUTILS\nextern pthread_mutex_t cgusb_lock;\n#endif\n\nextern cglock_t control_lock;\nextern pthread_mutex_t hash_lock;\nextern pthread_mutex_t console_lock;\nextern cglock_t ch_lock;\nextern pthread_rwlock_t mining_thr_lock;\nextern pthread_rwlock_t devices_lock;\n\nextern pthread_mutex_t restart_lock;\nextern pthread_cond_t restart_cond;\n\nextern void thread_reportin(struct thr_info *thr);\nextern void clear_stratum_shares(struct pool *pool);\nextern void set_target(unsigned char *dest_target, double diff);\nextern int restart_wait(unsigned int mstime);\n\nextern void kill_work(void);\n\nextern void reinit_device(struct cgpu_info *cgpu);\n\n#ifdef HAVE_ADL\nextern bool gpu_stats(int gpu, float *temp, int *engineclock, int *memclock, float *vddc, int *activity, int *fanspeed, int *fanpercent, int *powertune);\nextern int set_fanspeed(int gpu, int iFanSpeed);\nextern int set_vddc(int gpu, float fVddc);\nextern int set_engineclock(int gpu, int iEngineClock);\nextern int set_memoryclock(int gpu, int iMemoryClock);\n#endif\n\nextern void api(int thr_id);\n\nextern struct pool *current_pool(void);\nextern int enabled_pools;\nextern bool detect_stratum(struct pool *pool, char *url);\nextern void print_summary(void);\nextern struct pool *add_pool(void);\nextern bool add_pool_details(struct pool *pool, bool live, char *url, char *user, char *pass);\n\n#define MAX_GPUDEVICES 16\n\n#define MIN_INTENSITY -10\n#define _MIN_INTENSITY_STR \"-10\"\n#ifdef USE_SCRYPT\n#define MAX_INTENSITY 20\n#define _MAX_INTENSITY_STR \"20\"\n#else\n#define MAX_INTENSITY 14\n#define _MAX_INTENSITY_STR \"14\"\n#endif\n\nextern bool hotplug_mode;\nextern int hotplug_time;\nextern struct list_head scan_devices;\nextern int nDevs;\nextern int num_processors;\nextern int hw_errors;\nextern bool use_syslog;\nextern bool opt_quiet;\nextern struct thr_info *control_thr;\nextern struct thr_info **mining_thr;\nextern struct cgpu_info gpus[MAX_GPUDEVICES];\nextern int gpu_threads;\n#ifdef USE_SCRYPT\nextern bool opt_scrypt;\n#else\n#define opt_scrypt (0)\n#endif\nextern double total_secs;\nextern int mining_threads;\nextern int total_devices;\nextern struct cgpu_info **devices;\nextern int total_pools;\nextern struct pool **pools;\nextern struct strategies strategies[];\nextern enum pool_strategy pool_strategy;\nextern int opt_rotate_period;\nextern double total_mhashes_done;\nextern unsigned int new_blocks;\nextern unsigned int found_blocks;\nextern int total_accepted, total_rejected, total_diff1;;\nextern int total_getworks, total_stale, total_discarded;\nextern double total_diff_accepted, total_diff_rejected, total_diff_stale;\nextern unsigned int local_work;\nextern unsigned int total_go, total_ro;\nextern const int opt_cutofftemp;\nextern int opt_log_interval;\nextern unsigned long long global_hashrate;\nextern char *current_fullhash;\nextern double current_diff;\nextern uint64_t best_diff;\nextern struct timeval block_timeval;\n\n#ifdef HAVE_OPENCL\ntypedef struct {\n\tcl_uint ctx_a; cl_uint ctx_b; cl_uint ctx_c; cl_uint ctx_d;\n\tcl_uint ctx_e; cl_uint ctx_f; cl_uint ctx_g; cl_uint ctx_h;\n\tcl_uint cty_a; cl_uint cty_b; cl_uint cty_c; cl_uint cty_d;\n\tcl_uint cty_e; cl_uint cty_f; cl_uint cty_g; cl_uint cty_h;\n\tcl_uint merkle; cl_uint ntime; cl_uint nbits; cl_uint nonce;\n\tcl_uint fW0; cl_uint fW1; cl_uint fW2; cl_uint fW3; cl_uint fW15;\n\tcl_uint fW01r; cl_uint fcty_e; cl_uint fcty_e2;\n\tcl_uint W16; cl_uint W17; cl_uint W2;\n\tcl_uint PreVal4; cl_uint T1;\n\tcl_uint C1addK5; cl_uint D1A; cl_uint W2A; cl_uint W17_2;\n\tcl_uint PreVal4addT1; cl_uint T1substate0;\n\tcl_uint PreVal4_2;\n\tcl_uint PreVal0;\n\tcl_uint PreW18;\n\tcl_uint PreW19;\n\tcl_uint PreW31;\n\tcl_uint PreW32;\n\n\t/* For diakgcn */\n\tcl_uint B1addK6, PreVal0addK7, W16addK16, W17addK17;\n\tcl_uint zeroA, zeroB;\n\tcl_uint oneA, twoA, threeA, fourA, fiveA, sixA, sevenA;\n#ifdef USE_SCRYPT\n\tstruct work *work;\n#endif\n} dev_blk_ctx;\n#else\ntypedef struct {\n\tuint32_t nonce;\n} dev_blk_ctx;\n#endif\n\nstruct curl_ent {\n\tCURL *curl;\n\tstruct list_head node;\n\tstruct timeval tv;\n};\n\n/* Disabled needs to be the lowest enum as a freshly calloced value will then\n * equal disabled */\nenum pool_enable {\n\tPOOL_DISABLED,\n\tPOOL_ENABLED,\n\tPOOL_REJECTING,\n};\n\nstruct stratum_work {\n\tchar *job_id;\n\tchar *prev_hash;\n\tchar *coinbase1;\n\tchar *coinbase2;\n\tchar **merkle;\n\tchar *bbversion;\n\tchar *nbit;\n\tchar *ntime;\n\tbool clean;\n\n\tsize_t cb1_len;\n\tsize_t cb2_len;\n\tsize_t cb_len;\n\n\tsize_t header_len;\n\tint merkles;\n\tdouble diff;\n};\n\n#define RBUFSIZE 8192\n#define RECVSIZE (RBUFSIZE - 4)\n\nstruct pool {\n\tint pool_no;\n\tint prio;\n\tint accepted, rejected;\n\tint seq_rejects;\n\tint seq_getfails;\n\tint solved;\n\tint diff1;\n\tchar diff[8];\n\n\tdouble diff_accepted;\n\tdouble diff_rejected;\n\tdouble diff_stale;\n\n\tbool submit_fail;\n\tbool idle;\n\tbool lagging;\n\tbool probed;\n\tenum pool_enable enabled;\n\tbool submit_old;\n\tbool removed;\n\tbool lp_started;\n\n\tchar *hdr_path;\n\tchar *lp_url;\n\n\tunsigned int getwork_requested;\n\tunsigned int stale_shares;\n\tunsigned int discarded_work;\n\tunsigned int getfail_occasions;\n\tunsigned int remotefail_occasions;\n\tstruct timeval tv_idle;\n\n\tdouble utility;\n\tint last_shares, shares;\n\n\tchar *rpc_req;\n\tchar *rpc_url;\n\tchar *rpc_userpass;\n\tchar *rpc_user, *rpc_pass;\n\tcurl_proxytype rpc_proxytype;\n\tchar *rpc_proxy;\n\n\tpthread_mutex_t pool_lock;\n\tcglock_t data_lock;\n\n\tstruct thread_q *submit_q;\n\tstruct thread_q *getwork_q;\n\n\tpthread_t longpoll_thread;\n\tpthread_t test_thread;\n\tbool testing;\n\n\tint curls;\n\tpthread_cond_t cr_cond;\n\tstruct list_head curlring;\n\n\ttime_t last_share_time;\n\tdouble last_share_diff;\n\tuint64_t best_diff;\n\n\tstruct cgminer_stats cgminer_stats;\n\tstruct cgminer_pool_stats cgminer_pool_stats;\n\n\t/* Stratum variables */\n\tchar *stratum_url;\n\tchar *stratum_port;\n\tstruct addrinfo stratum_hints;\n\tSOCKETTYPE sock;\n\tchar *sockbuf;\n\tsize_t sockbuf_size;\n\tchar *sockaddr_url; /* stripped url used for sockaddr */\n\tchar *nonce1;\n\tsize_t n1_len;\n\tuint32_t nonce2;\n\tint n2size;\n\tchar *sessionid;\n\tbool has_stratum;\n\tbool stratum_active;\n\tbool stratum_init;\n\tbool stratum_notify;\n\tstruct stratum_work swork;\n\tpthread_t stratum_thread;\n\tpthread_mutex_t stratum_lock;\n\tint sshares; /* stratum shares submitted waiting on response */\n\n\t/* GBT  variables */\n\tbool has_gbt;\n\tcglock_t gbt_lock;\n\tunsigned char previousblockhash[32];\n\tunsigned char gbt_target[32];\n\tchar *coinbasetxn;\n\tchar *longpollid;\n\tchar *gbt_workid;\n\tint gbt_expires;\n\tuint32_t gbt_version;\n\tuint32_t curtime;\n\tuint32_t gbt_bits;\n\tunsigned char *gbt_coinbase;\n\tunsigned char *txn_hashes;\n\tint gbt_txns;\n\tint coinbase_len;\n\tstruct timeval tv_lastwork;\n};\n\n#define GETWORK_MODE_TESTPOOL 'T'\n#define GETWORK_MODE_POOL 'P'\n#define GETWORK_MODE_LP 'L'\n#define GETWORK_MODE_BENCHMARK 'B'\n#define GETWORK_MODE_STRATUM 'S'\n#define GETWORK_MODE_GBT 'G'\n\nstruct work {\n\tunsigned char\tdata[128];\n\tunsigned char\tmidstate[32];\n\tunsigned char\ttarget[32];\n\tunsigned char\thash[32];\n\n#ifdef USE_SCRYPT\n\tunsigned char\tdevice_target[32];\n#endif\n\tdouble\t\tdevice_diff;\n\tuint64_t\tshare_diff;\n\n\tint\t\trolls;\n\n\tdev_blk_ctx\tblk;\n\n\tstruct thr_info\t*thr;\n\tint\t\tthr_id;\n\tstruct pool\t*pool;\n\tstruct timeval\ttv_staged;\n\n\tbool\t\tmined;\n\tbool\t\tclone;\n\tbool\t\tcloned;\n\tint\t\trolltime;\n\tbool\t\tlongpoll;\n\tbool\t\tstale;\n\tbool\t\tmandatory;\n\tbool\t\tblock;\n\tbool\t\tqueued;\n\n\tbool\t\tstratum;\n\tchar \t\t*job_id;\n\tchar\t\t*nonce2;\n\tchar\t\t*ntime;\n\tdouble\t\tsdiff;\n\tchar\t\t*nonce1;\n\n\tbool\t\tgbt;\n\tchar\t\t*gbt_coinbase;\n\tint\t\tgbt_txns;\n\n\tunsigned int\twork_block;\n\tint\t\tid;\n\tUT_hash_handle\thh;\n\n\tdouble\t\twork_difficulty;\n\n\t// Allow devices to identify work if multiple sub-devices\n\tint\t\tsubid;\n\t// Allow devices to flag work for their own purposes\n\tbool\t\tdevflag;\n\n\tstruct timeval\ttv_getwork;\n\tstruct timeval\ttv_getwork_reply;\n\tstruct timeval\ttv_cloned;\n\tstruct timeval\ttv_work_start;\n\tstruct timeval\ttv_work_found;\n\tchar\t\tgetwork_mode;\n};\n\n#ifdef USE_MODMINER \nstruct modminer_fpga_state {\n\tbool work_running;\n\tstruct work running_work;\n\tstruct timeval tv_workstart;\n\tuint32_t hashes;\n\n\tchar next_work_cmd[46];\n\tchar fpgaid;\n\n\tbool overheated;\n\tbool new_work;\n\n\tuint32_t shares;\n\tuint32_t shares_last_hw;\n\tuint32_t hw_errors;\n\tuint32_t shares_to_good;\n\tuint32_t timeout_fail;\n\tuint32_t success_more;\n\tstruct timeval last_changed;\n\tstruct timeval last_nonce;\n\tstruct timeval first_work;\n\tbool death_stage_one;\n\tbool tried_two_byte_temp;\n\tbool one_byte_temp;\n};\n#endif\n\nextern void get_datestamp(char *, struct timeval *);\nextern void inc_hw_errors(struct thr_info *thr);\nextern void submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);\nextern struct work *get_queued(struct cgpu_info *cgpu);\nextern struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);\nextern struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);\nextern void work_completed(struct cgpu_info *cgpu, struct work *work);\nextern void hash_queued_work(struct thr_info *mythr);\nextern void tailsprintf(char *f, const char *fmt, ...);\nextern void wlogprint(const char *f, ...);\nextern int curses_int(const char *query);\nextern char *curses_input(const char *query);\nextern void kill_work(void);\nextern void switch_pools(struct pool *selected);\nextern void discard_work(struct work *work);\nextern void remove_pool(struct pool *pool);\nextern void write_config(FILE *fcfg);\nextern void zero_bestshare(void);\nextern void zero_stats(void);\nextern void default_save_file(char *filename);\nextern bool log_curses_only(int prio, const char *f, va_list ap);\nextern void clear_logwin(void);\nextern bool pool_tclear(struct pool *pool, bool *var);\nextern struct thread_q *tq_new(void);\nextern void tq_free(struct thread_q *tq);\nextern bool tq_push(struct thread_q *tq, void *data);\nextern void *tq_pop(struct thread_q *tq, const struct timespec *abstime);\nextern void tq_freeze(struct thread_q *tq);\nextern void tq_thaw(struct thread_q *tq);\nextern bool successful_connect;\nextern void adl(void);\nextern void app_restart(void);\nextern void clean_work(struct work *work);\nextern void free_work(struct work *work);\nextern void __copy_work(struct work *work, struct work *base_work);\nextern struct work *copy_work(struct work *base_work);\nextern struct thr_info *get_thread(int thr_id);\nextern struct cgpu_info *get_devices(int id);\n\nenum api_data_type {\n\tAPI_ESCAPE,\n\tAPI_STRING,\n\tAPI_CONST,\n\tAPI_INT,\n\tAPI_UINT,\n\tAPI_UINT32,\n\tAPI_UINT64,\n\tAPI_DOUBLE,\n\tAPI_ELAPSED,\n\tAPI_BOOL,\n\tAPI_TIMEVAL,\n\tAPI_TIME,\n\tAPI_MHS,\n\tAPI_MHTOTAL,\n\tAPI_TEMP,\n\tAPI_UTILITY,\n\tAPI_FREQ,\n\tAPI_VOLTS,\n\tAPI_HS,\n\tAPI_DIFF\n};\n\nstruct api_data {\n\tenum api_data_type type;\n\tchar *name;\n\tvoid *data;\n\tbool data_was_malloc;\n\tstruct api_data *prev;\n\tstruct api_data *next;\n};\n\nextern struct api_data *api_add_escape(struct api_data *root, char *name, char *data, bool copy_data);\nextern struct api_data *api_add_string(struct api_data *root, char *name, char *data, bool copy_data);\nextern struct api_data *api_add_const(struct api_data *root, char *name, const char *data, bool copy_data);\nextern struct api_data *api_add_int(struct api_data *root, char *name, int *data, bool copy_data);\nextern struct api_data *api_add_uint(struct api_data *root, char *name, unsigned int *data, bool copy_data);\nextern struct api_data *api_add_uint32(struct api_data *root, char *name, uint32_t *data, bool copy_data);\nextern struct api_data *api_add_uint64(struct api_data *root, char *name, uint64_t *data, bool copy_data);\nextern struct api_data *api_add_double(struct api_data *root, char *name, double *data, bool copy_data);\nextern struct api_data *api_add_elapsed(struct api_data *root, char *name, double *data, bool copy_data);\nextern struct api_data *api_add_bool(struct api_data *root, char *name, bool *data, bool copy_data);\nextern struct api_data *api_add_timeval(struct api_data *root, char *name, struct timeval *data, bool copy_data);\nextern struct api_data *api_add_time(struct api_data *root, char *name, time_t *data, bool copy_data);\nextern struct api_data *api_add_mhs(struct api_data *root, char *name, double *data, bool copy_data);\nextern struct api_data *api_add_mhstotal(struct api_data *root, char *name, double *data, bool copy_data);\nextern struct api_data *api_add_temp(struct api_data *root, char *name, float *data, bool copy_data);\nextern struct api_data *api_add_utility(struct api_data *root, char *name, double *data, bool copy_data);\nextern struct api_data *api_add_freq(struct api_data *root, char *name, double *data, bool copy_data);\nextern struct api_data *api_add_volts(struct api_data *root, char *name, float *data, bool copy_data);\nextern struct api_data *api_add_hs(struct api_data *root, char *name, double *data, bool copy_data);\nextern struct api_data *api_add_diff(struct api_data *root, char *name, double *data, bool copy_data);\n\n#endif /* __MINER_H__ */\n"
  },
  {
    "path": "experimental/Ztex-1-15y/pbkdfengine.v",
    "content": "/* pbkdfengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`define ICARUS\t\t\t// Comment this out when using the altera virtual_wire interface in ltcminer.v\n\t\n`timescale 1ns/1ps\n\nmodule pbkdfengine\n\t(hash_clk, pbkdf_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce,\n\t\t\tsalsa_din, salsa_dout, salsa_busy, salsa_result, salsa_reset, salsa_start, salsa_shift, hash_out);\n\n\tinput hash_clk;\t\t\t// Just drives shift register\n\tinput pbkdf_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\n\toutput reg [31:0] nonce_out;\n\toutput reg [31:0] hash_out;\t\t// Hash value for nonce_out (ztex port)\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] salsa_dout;\n\toutput [SBITS-1:0] salsa_din;\n\n\tinput salsa_busy, salsa_result;\t// NB hash_clk domain\n\toutput salsa_reset;\n\toutput salsa_start;\n\toutput reg salsa_shift = 1'b0;\t// NB hash_clk domain\n\n\treg [4:0]resetcycles = 4'd0;\n\treg reset = 1'b0;\n\tassign salsa_reset = reset;\t\t// Propagate reset to salsaengine\n\n`ifdef WANTCYCLICRESET\t\t\n\treg [23:0]cycresetcount = 24'd0;\n`endif\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\t// Hard code a 31 cycle reset (NB assumes THREADS=16 in salsaengine, else we need more)\n\t\t// NB hash_clk is faster than pbkdf_clk so the salsaengine will actually be initialised well before\n\t\t// this period ends, but keep to 15 for now as simulation uses equal pbkdf and salsa clock speeds.\n\t\tresetcycles <= resetcycles + 1'd1;\n\t\tif (resetcycles == 0)\n\t\t\treset <= 1'b1;\n\t\tif (resetcycles == 31)\n\t\tbegin\n\t\t\treset <= 1'b0;\n\t\t\tresetcycles <= 31;\n\t\tend\n`ifdef WANTCYCLICRESET\t\t\n\t\t// Cyclical reset every 2_500_000 clocks to ensure salsa pipeline does not drift out of sync\n\t\t// This may be unneccessary if we reset every loadnonce\n\t\t// Actually it seems to do more harm than good, so disabled\n\t\tcycresetcount <= cycresetcount + 1'd1;\n\t\tif (cycresetcount == 2_500_000)\t// 10 per second at 25MHz (adjust as neccessary)\n\t\tbegin\n\t\t\tcycresetcount <= 24'd0;\n\t\t\tresetcycles <= 5'd0;\n\t\tend\n`endif\t\t\n\t\t// Reset on loadnonce (the hash results will be junk anyway since data changes, so no loss of shares)\n\t\tif (loadnonce)\n\t\t\tresetcycles <= 5'd0;\n\tend\n\t\n\t`ifndef ICARUS\n\treg [31:0] nonce_previous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\t`endif\n\n\t`ifndef NOMULTICORE\n\t`ifdef SIM\n\t\treg [27:0] nonce_cnt = 28'h318f;\t// Start point for simulation (NB also define SIM in serial.v)\n\t`else\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t`endif\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\treg [31:0] nonce_sr = 32'd0;\t\t// Nonce is shifted to salsaengine for storage/retrieval (hash_clk domain)\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\treg [2:0] nonce_wait = 3'd0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [2:0] blockcnt = 3'd0;\t\t// Takes values 1..5 for block iteration\n\treg [1023:0] Xbuf = 1024'd0;\t// Shared input/output buffer and shift register (hash_clk domain)\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\tassign salsa_din = Xbuf[1023:1024-SBITS];\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\t\n\t// MixOut is little-endian word format to match scrypt.c so convert back to big-endian\n\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] mix;\n\t\tassign mix = Xbuf[`IDX(i)];\t\t// NB MixOut now shares Xbuf since shifted in/out\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\n\t// Interface control. This should be OK provided the threads remain evenly spaced (hence we reset on loadnonce)\n\t\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\treg Clr_SMixOutRdy = 1'b0;\n\twire Clr_SMixInRdy;\n\twire Set_SMixOutRdy;\n\n\treg [4:0]salsa_busy_d = 0;\t\t\t// Sync to pbkdf_clk domain\n\treg [4:0]salsa_result_d = 0;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\t// Sync to pbkdf_clk domain\n\t\tsalsa_busy_d[0] <= salsa_busy;\n\t\tif (salsa_busy & ~ salsa_busy_d[0])\n\t\t\tsalsa_busy_d[1] <= ~ salsa_busy_d[1];\t\t// Toggle on busy going high\n\t\t\n\t\tsalsa_result_d[0] <= salsa_result;\n\t\tif (salsa_result & ~ salsa_result_d[0])\n\t\t\tsalsa_result_d[1] <= ~ salsa_result_d[1];\t// Toggle on result going high\n\tend\n\t\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tsalsa_busy_d[4:2] <= salsa_busy_d[3:1];\n\t\tsalsa_result_d[4:2] <= salsa_result_d[3:1];\n\t\t\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\t\t\t\n\t\t// CARE there is a race with Set_SMixInRdy, Clr_SMixOutRdy which are set in the FSM\n\t\t// Need to assert reset for several cycles to ensure consistency (acutally use 15 since salsaengine needs more)\n\t\tif (reset)\n\t\tbegin\t\t\t\t\t\t\t// Reset takes priority\n\t\t\tSMixInRdy_state <= 1'b0;\n\t\t\tSMixOutRdy_state <= 1'b0;\n\t\tend\n\tend\n\t\n\tassign Clr_SMixInRdy = SMixInRdy_state & (salsa_busy_d[3] ^ salsa_busy_d[4]);\t\t\t// Clear on transition to busy\n\t\n\tassign Set_SMixOutRdy = ~SMixOutRdy_state & (salsa_result_d[3] ^ salsa_result_d[4]);\t// Set on transition to result\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\tassign salsa_start = SMixInRdy;\n\t\t\n\t// Clock crossing flags for shift register control (span pbkdf_clk, hash_clk domains)\n\treg [3:0]Xbuf_load_request = 1'b0;\n\treg [3:0]shift_request =  1'b0;\n\treg [3:0]shift_acknowledge = 1'b0;\n\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz)\n\t\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_NONCE=22, S_SHIFT_IN=41, S_SHIFT_OUT=42,\t\t\t\t// Direction relative to salsa unit\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\treg start_output = 0;\n\n\talways @ (posedge pbkdf_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\n\t\tshift_acknowledge[3:1] <= shift_acknowledge[2:0];\t// Clock crossing\n\n\t\t`ifdef ICARUS\n\t\tif (loadnonce)\t\t\t\t// Separate clock domains means comparison is unsafe\n\t\t`else\n\t\tif (loadnonce || (nonce_previous_load != data3[127:96]))\n\t\t`endif\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_previous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\t`ifndef ICARUS\n\t\t\tnonce_previous_load <= data3[127:96];\n\t\t\t`endif\n\t\tend\n\t\t\n\t\tif (reset == 1'b1)\n\t\tbegin\n\t\t\tstate <= S_IDLE;\n\t\t\tstart_output <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tif (SMixOutRdy & ~start_output)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\t// Request shifter to start\n\t\t\t\t\t\tstate <= S_SHIFT_OUT;\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (start_output ||\t// Process output\n\t\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'b0;\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\t\tblockcnt <= 3'd1;\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_sr : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\t\t\n\t\t\t\tS_B6: begin\n\t\t\t\t\t\tkhash <= tx_hash;\t\t// Save temporarily (for Xbuf)\n\n\t\t\t\t\t\tXbuf_load_request[0] <= ~Xbuf_load_request[0];\t// NB also loads nonce_sr\n\n\t\t\t\t\t\tif (blockcnt == 3'd5)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tnonce_wait <= 3'd7;\n\t\t\t\t\t\t\tstate <= S_NONCE;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\t29'd0, blockcnt, nonce, data3[95:0] }; // blockcnt is 3 bits, top 29 are hardcoded 0\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1'd1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_NONCE: begin\n\t\t\t\t\t\t// Need to delay a few clocks for Xbuf_load_request to complete\n\t\t\t\t\t\tnonce_wait <= nonce_wait - 1'd1;\n\t\t\t\t\t\tif (nonce_wait == 0)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 1'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 1'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\t\tshift_request[0] <= ~shift_request[0];\n\t\t\t\t\t\t\tstate <= S_SHIFT_IN;\n\t\t\t\t\t\tend\n\t\t\t\t\n\t\t\t\tend\n\t\t\t\tS_SHIFT_IN: begin\t\t\t\t\t\t\t// Shifting from PBKDF2_SHA256 to salsa\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tSet_SMixInRdy <= 1'd1;\t\t\t\t// Flag salsa to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_SHIFT_OUT: begin\t\t\t\t\t\t\t// Shifting from salsa to PBKDF2_SHA256\n\t\t\t\t\t\tif (shift_acknowledge[3] != shift_acknowledge[2])\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tstart_output <= 1'd1;\t\t\t\t// Flag self to start\n\t\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\tnonce_out <= nonce_sr;\t\t\t// Ztex port\n\t\t\t\t\t\thash_out <= tx_hash[255:224];\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_sr;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n\tend\n\n\t// Shift register control - NB hash_clk domain\n\t\n\treg\t[10:0]shift_count = 11'd0;\t// hash_clk domain\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tif (reset)\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b0;\n\t\t\tshift_count <= 11'd0;\n\t\tend\n\n\t\t// Clock crossing logic\n\t\tXbuf_load_request[3:1] <= Xbuf_load_request[2:0];\n\t\tif (Xbuf_load_request[3] != Xbuf_load_request[2])\n\t\tbegin\n\t\t\t// Shift output into X buffer from MSB->LSB\n\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\tXbuf[1023:768] <= khash;\n\n\t\t\tnonce_sr <= nonce;\t// Loaded several times, but of no consequence\n\t\tend\n\t\t\n\t\tshift_request[3:1] <= shift_request[2:0];\n\t\tif (shift_request[3] != shift_request[2])\n\t\tbegin\n\t\t\tsalsa_shift <= 1'b1;\n\t\tend\n\n\t\tif (salsa_shift)\n\t\tbegin\n\t\t\tshift_count <= shift_count + 1'b1;\n\t\t\tXbuf <= { Xbuf[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], salsa_dout };\n\t\tend\n\t\t\n\t\tif (shift_count == (1024+32)/SBITS-1)\n\t\tbegin\n\t\t\tshift_acknowledge[0] = ~shift_acknowledge[0];\n\t\t\tshift_count <= 0;\n\t\t\tsalsa_shift <= 0;\n\t\tend\n\tend\n\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(pbkdf_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\nendmodule"
  },
  {
    "path": "experimental/Ztex-1-15y/salsa_slowsixteen.v",
    "content": "/* salsa_slowsixteen.v\n*\n* Copyright (c) 2013 kramble\n* Derived from scrypt.c Copyright 2009 Colin Percival, 2011 ArtForz\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\nmodule salsa (clk, B, Bx, Bo, X0out, Xaddr);\n\n// Latency 16 clock cycles, approx 20nS propagation delay (SLOW!)\n\ninput clk;\n// input feedback;\ninput [511:0]B;\ninput [511:0]Bx;\n// output reg [511:0]Bo;\t// Output is registered\noutput [511:0]Bo;\t\t\t// Output is async\noutput [511:0]X0out;\t\t// Becomes new X0\noutput [9:0] Xaddr;\nwire [9:0] xa1, xa2, xa3, xa4, ya1, ya2, ya3, ya4;\n\nreg [511:0]x1d1, x1d1a;\nreg [511:0]x1d2, x1d2a;\nreg [511:0]x1d3, x1d3a;\nreg [511:0]x1d4, x1d4a;\n\nreg [511:0]Xod1, Xod1a;\nreg [511:0]Xod2, Xod2a;\nreg [511:0]Xod3, Xod3a;\nreg [511:0]Xod4, X0out;\n\nreg [511:0]xxd1, xxd1a;\nreg [511:0]xxd2, xxd2a;\nreg [511:0]xxd3, xxd3a;\nreg [511:0]xxd4, xxd4a;\n\nreg [511:0]yyd1, yyd1a;\nreg [511:0]yyd2, yyd2a;\nreg [511:0]yyd3, yyd3a;\nreg [511:0]yyd4, yyd4a;\n\nwire [511:0]xx;\t\t\t// Initial xor\nwire [511:0]x1;\t\t\t// Salasa core outputs\nwire [511:0]x2;\nwire [511:0]x3;\nwire [511:0]xr;\nwire [511:0]Xo;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsax1 (clk, xx, x1, xa1);\nsalsa_core salsax2 (clk, x1, x2, xa2);\nsalsa_core salsax3 (clk, x2, x3, xa3);\nsalsa_core salsax4 (clk, x3, xr, xa4);\n\nwire [511:0]yy;\t\t\t// Initial xor\nwire [511:0]y1;\t\t\t// Salasa core outputs\nwire [511:0]y2;\nwire [511:0]y3;\nwire [511:0]yr;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsay1 (clk, yy, y1, ya1);\nsalsa_core salsay2 (clk, y1, y2, ya2);\nsalsa_core salsay3 (clk, y2, y3, ya3);\nsalsa_core salsay4 (clk, y3, yr, ya4);\n\nassign Xaddr = yyd4[9:0] + ya4;\n\ngenvar i;\ngenerate\n\tfor (i = 0; i < 16; i = i + 1) begin : XX\n\t\t// Initial XOR. NB this adds to the propagation delay of the first salsa, may want register it.\n\t\tassign xx[`IDX(i)] = B[`IDX(i)] ^ Bx[`IDX(i)];\n\t\tassign Xo[`IDX(i)] = xxd4a[`IDX(i)] + xr[`IDX(i)];\n\t\tassign yy[`IDX(i)] = x1d4a[`IDX(i)] ^ Xo[`IDX(i)];\n\t\tassign Bo[`IDX(i)] = yyd4a[`IDX(i)] + yr[`IDX(i)];\t// Async output\n\tend\nendgenerate\n\nalways @ (posedge clk)\nbegin\n\tx1d1 <= Bx;\n\tx1d1a <= x1d1;\n\tx1d2 <= x1d1a;\n\tx1d2a <= x1d2;\n\tx1d3 <= x1d2a;\n\tx1d3a <= x1d3;\n\tx1d4 <= x1d3a;\n\tx1d4a <= x1d4;\n\tXod1 <= Xo;\n\tXod1a <= Xod1;\n\tXod2 <= Xod1a;\n\tXod2a <= Xod2;\n\tXod3 <= Xod2a;\n\tXod3a <= Xod3;\n\tXod4 <= Xod3a;\n\tX0out <= Xod4;\t// We output this to become new X0\n\n\txxd1 <= xx;\n\txxd1a <= xxd1;\n\txxd2 <= xxd1a;\n\txxd2a <= xxd2;\n\txxd3 <= xxd2a;\n\txxd3a <= xxd3;\n\txxd4 <= xxd3a;\n\txxd4a <= xxd4;\n\n\tyyd1 <= yy;\n\tyyd1a <= yyd1;\n\tyyd2 <= yyd1a;\n\tyyd2a <= yyd2;\n\tyyd3 <= yyd2a;\n\tyyd3a <= yyd3;\n\tyyd4 <= yyd3a;\n\tyyd4a <= yyd4;\n\nend\n\nendmodule\n\nmodule salsa_core (clk, xx, out, Xaddr);\n\ninput clk;\ninput [511:0]xx;\noutput reg [511:0]out;\t\t// Output is registered\noutput [9:0] Xaddr;\t\t\t// Address output unregistered\n\n// This is clunky due to my lack of verilog skills but it works so elegance can come later\n\nwire [31:0]c00;\t\t\t// Column results\nwire [31:0]c01;\nwire [31:0]c02;\nwire [31:0]c03;\nwire [31:0]c04;\nwire [31:0]c05;\nwire [31:0]c06;\nwire [31:0]c07;\nwire [31:0]c08;\nwire [31:0]c09;\nwire [31:0]c10;\nwire [31:0]c11;\nwire [31:0]c12;\nwire [31:0]c13;\nwire [31:0]c14;\nwire [31:0]c15;\n\nwire [31:0]r00;\t\t\t// Row results\nwire [31:0]r01;\nwire [31:0]r02;\nwire [31:0]r03;\nwire [31:0]r04;\nwire [31:0]r05;\nwire [31:0]r06;\nwire [31:0]r07;\nwire [31:0]r08;\nwire [31:0]r09;\nwire [31:0]r10;\nwire [31:0]r11;\nwire [31:0]r12;\nwire [31:0]r13;\nwire [31:0]r14;\nwire [31:0]r15;\n\nwire [31:0]c00s;\t\t\t// Column sums\nwire [31:0]c01s;\nwire [31:0]c02s;\nwire [31:0]c03s;\nwire [31:0]c04s;\nwire [31:0]c05s;\nwire [31:0]c06s;\nwire [31:0]c07s;\nwire [31:0]c08s;\nwire [31:0]c09s;\nwire [31:0]c10s;\nwire [31:0]c11s;\nwire [31:0]c12s;\nwire [31:0]c13s;\nwire [31:0]c14s;\nwire [31:0]c15s;\n\nwire [31:0]r00s;\t\t\t// Row sums\nwire [31:0]r01s;\nwire [31:0]r02s;\nwire [31:0]r03s;\nwire [31:0]r04s;\nwire [31:0]r05s;\nwire [31:0]r06s;\nwire [31:0]r07s;\nwire [31:0]r08s;\nwire [31:0]r09s;\nwire [31:0]r10s;\nwire [31:0]r11s;\nwire [31:0]r12s;\nwire [31:0]r13s;\nwire [31:0]r14s;\nwire [31:0]r15s;\n\nreg [31:0]c00d;\t\t\t// Column results registered\nreg [31:0]c01d;\nreg [31:0]c02d;\nreg [31:0]c03d;\nreg [31:0]c04d;\nreg [31:0]c05d;\nreg [31:0]c06d;\nreg [31:0]c07d;\nreg [31:0]c08d;\nreg [31:0]c09d;\nreg [31:0]c10d;\nreg [31:0]c11d;\nreg [31:0]c12d;\nreg [31:0]c13d;\nreg [31:0]c14d;\nreg [31:0]c15d;\n\n/* From scrypt.c\n\n#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))\n\tfor (i = 0; i < 8; i += 2) {\n\t\t// Operate on columns\n\t\tx04 ^= R(x00+x12, 7);\tx09 ^= R(x05+x01, 7);\tx14 ^= R(x10+x06, 7);\tx03 ^= R(x15+x11, 7);\n\t\tx08 ^= R(x04+x00, 9);\tx13 ^= R(x09+x05, 9);\tx02 ^= R(x14+x10, 9);\tx07 ^= R(x03+x15, 9);\n\t\tx12 ^= R(x08+x04,13);\tx01 ^= R(x13+x09,13);\tx06 ^= R(x02+x14,13);\tx11 ^= R(x07+x03,13);\n\t\tx00 ^= R(x12+x08,18);\tx05 ^= R(x01+x13,18);\tx10 ^= R(x06+x02,18);\tx15 ^= R(x11+x07,18);\n\n\t\t// Operate on rows\n\t\tx01 ^= R(x00+x03, 7);\tx06 ^= R(x05+x04, 7);\tx11 ^= R(x10+x09, 7);\tx12 ^= R(x15+x14, 7);\n\t\tx02 ^= R(x01+x00, 9);\tx07 ^= R(x06+x05, 9);\tx08 ^= R(x11+x10, 9);\tx13 ^= R(x12+x15, 9);\n\t\tx03 ^= R(x02+x01,13);\tx04 ^= R(x07+x06,13);\tx09 ^= R(x08+x11,13);\tx14 ^= R(x13+x12,13);\n\t\tx00 ^= R(x03+x02,18);\tx05 ^= R(x04+x07,18);\tx10 ^= R(x09+x08,18);\tx15 ^= R(x14+x13,18);\n\t}\n*/\n\n// cols\n\nassign c04s = xx[`IDX(0)] + xx[`IDX(12)];\nassign c04 = xx[`IDX(4)] ^ { c04s[24:0], c04s[31:25] };\nassign c09s = xx[`IDX(5)] + xx[`IDX(1)];\nassign c09 = xx[`IDX(9)] ^ { c09s[24:0], c09s[31:25] };\nassign c14s = xx[`IDX(10)] + xx[`IDX(6)];\nassign c14 = xx[`IDX(14)] ^ { c14s[24:0], c14s[31:25] };\nassign c03s = xx[`IDX(15)] + xx[`IDX(11)];\nassign c03 = xx[`IDX(03)] ^ { c03s[24:0], c03s[31:25] };\n\nassign c08s = c04 + xx[`IDX(0)];\nassign c08 = xx[`IDX(8)] ^ { c08s[22:0], c08s[31:23] };\nassign c13s = c09 + xx[`IDX(5)];\nassign c13 = xx[`IDX(13)] ^ { c13s[22:0], c13s[31:23] };\nassign c02s = c14 + xx[`IDX(10)];\nassign c02 = xx[`IDX(2)] ^ { c02s[22:0], c02s[31:23] };\nassign c07s = c03 + xx[`IDX(15)];\nassign c07 = xx[`IDX(7)] ^ { c07s[22:0], c07s[31:23] };\n\nassign c12s = c08 + c04;\nassign c12 = xx[`IDX(12)] ^ { c12s[18:0], c12s[31:19] };\nassign c01s = c13 + c09;\nassign c01 = xx[`IDX(1)] ^ { c01s[18:0], c01s[31:19] };\nassign c06s = c02 + c14;\nassign c06 = xx[`IDX(6)] ^ { c06s[18:0], c06s[31:19] };\nassign c11s = c07 + c03;\nassign c11 = xx[`IDX(11)] ^ { c11s[18:0], c11s[31:19] };\n\nassign c00s = c12 + c08;\nassign c00 = xx[`IDX(0)] ^ { c00s[13:0], c00s[31:14] };\nassign c05s = c01 + c13;\nassign c05 = xx[`IDX(5)] ^ { c05s[13:0], c05s[31:14] };\nassign c10s = c06 + c02;\nassign c10 = xx[`IDX(10)] ^ { c10s[13:0], c10s[31:14] };\nassign c15s = c11 + c07;\nassign c15 = xx[`IDX(15)] ^ { c15s[13:0], c15s[31:14] };\n\n// rows\n\nassign r01s = c00d + c03d;\nassign r01 = c01d ^ { r01s[24:0], r01s[31:25] };\nassign r06s = c05d + c04d;\nassign r06 = c06d ^ { r06s[24:0], r06s[31:25] };\nassign r11s = c10d + c09d;\nassign r11 = c11d ^ { r11s[24:0], r11s[31:25] };\nassign r12s = c15d + c14d;\nassign r12 = c12d ^ { r12s[24:0], r12s[31:25] };\n\nassign r02s = r01 + c00d;\nassign r02 = c02d ^ { r02s[22:0], r02s[31:23] };\nassign r07s = r06 + c05d;\nassign r07 = c07d ^ { r07s[22:0], r07s[31:23] };\nassign r08s = r11 + c10d;\nassign r08 = c08d ^ { r08s[22:0], r08s[31:23] };\nassign r13s = r12 + c15d;\nassign r13 = c13d ^ { r13s[22:0], r13s[31:23] };\n\nassign r03s = r02 + r01;\nassign r03 = c03d ^ { r03s[18:0], r03s[31:19] };\nassign r04s = r07 + r06;\nassign r04 = c04d ^ { r04s[18:0], r04s[31:19] };\nassign r09s = r08 + r11;\nassign r09 = c09d ^ { r09s[18:0], r09s[31:19] };\nassign r14s = r13 + r12;\nassign r14 = c14d ^ { r14s[18:0], r14s[31:19] };\n\nassign r00s = r03 + r02;\nassign r00 = c00d ^ { r00s[13:0], r00s[31:14] };\nassign r05s = r04 + r07;\nassign r05 = c05d ^ { r05s[13:0], r05s[31:14] };\nassign r10s = r09 + r08;\nassign r10 = c10d ^ { r10s[13:0], r10s[31:14] };\nassign r15s = r14 + r13;\nassign r15 = c15d ^ { r15s[13:0], r15s[31:14] };\n\nwire [511:0]xo;\t\t\t// Rename row results\nassign xo = { r15, r14, r13, r12, r11, r10, r09, r08, r07, r06, r05, r04, r03, r02, r01, r00 };\n\nassign Xaddr = xo[9:0];\t// Unregistered output\n\nalways @ (posedge clk)\nbegin\n\tc00d <= c00;\n\tc01d <= c01;\n\tc02d <= c02;\n\tc03d <= c03;\n\tc04d <= c04;\n\tc05d <= c05;\n\tc06d <= c06;\n\tc07d <= c07;\n\tc08d <= c08;\n\tc09d <= c09;\n\tc10d <= c10;\n\tc11d <= c11;\n\tc12d <= c12;\n\tc13d <= c13;\n\tc14d <= c14;\n\tc15d <= c15;\n\tout <= xo;\t\t// Registered output\nend\n\nendmodule\n"
  },
  {
    "path": "experimental/Ztex-1-15y/salsaengine.v",
    "content": "/* salsaengine.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n// NB HALFRAM no longer applies, configure via parameters ADDRBITS, THREADS\n\n// Bracket this config option in SIM so we don't accidentally leave it set in a live build\n`ifdef SIM\n//`define ONETHREAD\t// Start one thread only (for SIMULATION less confusing and faster startup)\n`endif\n\n`timescale 1ns/1ps\n\nmodule salsaengine (hash_clk, reset, din, dout, shift, start, busy, result );\n\n\n\tinput hash_clk;\n\tinput reset;\t// NB pbkdf_clk domain (need a long reset (at least THREADS+4) to initialize correctly, this is done in pbkdfengine (15 cycles)\n\tinput shift;\n\tinput start;\t// NB pbkdf_clk domain\n\toutput busy;\n\toutput reg result = 1'b0;\n\n\tparameter SBITS = 8;\t\t// Shift data path width\n\tinput [SBITS-1:0] din;\n\toutput [SBITS-1:0] dout;\n\n\t// Configure ADDRBITS to allocate RAM for core (automatically sets LOOKAHEAD_GAP)\n\t// NB do not use ADDRBITS > 13 for THREADS=8 since this corresponds to more than a full scratchpad\n\n\t// These settings are now overriden in ltcminer_icarus.v determined by LOCAL_MINERS ...\n\t// parameter ADDRBITS = 13;\t// 8MBit RAM allocated to core, full scratchpad (will not fit LX150)\n\tparameter ADDRBITS = 12;\t// 4MBit RAM allocated to core, half scratchpad\n\t// parameter ADDRBITS = 11;\t// 2MBit RAM allocated to core, quarter scratchpad\n\t// parameter ADDRBITS = 10;\t// 1MBit RAM allocated to core, eighth scratchpad\n\n\t// Do not change THREADS - this must match the salsa pipeline (code is untested for other values)\n\tparameter THREADS = 16;\t\t// NB Phase has THREADS+1 cycles\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n\tparameter THREADS_BITS = clog2(THREADS);\n\t\n\t// Workaround for range-reversal error in inactive code when ADDRBITS=13\n\tparameter ADDRBITSX = (ADDRBITS == 13) ? ADDRBITS-1 : ADDRBITS;\n\n\treg [THREADS_BITS:0]phase = 0;\n\treg [THREADS_BITS:0]phase_d = THREADS+1;\n\treg reset_d=0, fsmreset=0, start_d=0, fsmstart=0;\n\n\talways @ (posedge hash_clk)\t\t// Phase control and sync\n\tbegin\n\t\tphase <= (phase == THREADS) ? 0 : phase + 1;\n\t\tphase_d <= phase;\n\t\treset_d <= reset;\t\t\t// Synchronise to hash_clk domain\n\t\tfsmreset <= reset_d;\n\t\tstart_d <= start;\n\t\tfsmstart <= start_d;\n\tend\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\tparameter XSnull = 0, XSload = 1, XSmix = 2, XSram = 4;\t\t\t// One-hot since these map directly to mux contrls\n\treg [2:0] XCtl = XSnull;\n\n\tparameter R_IDLE=0, R_START=1, R_WRITE=2, R_MIX=3, R_INT=4, R_WAIT=5;\n\treg [2:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs\n\treg addrsourceMix = 1'b0;\n\treg datasourceLoad = 1'b0;\n\treg addrsourceSave = 1'b0;\n\treg resultsourceRam = 1'b0;\n\treg xoren = 1'b1;\n\treg [THREADS_BITS+1:0] intcycles = 0;\t// Number of interpolation cycles required ... How many do we need? Say THREADS_BITS+1\n\n\twire [511:0] Xmix;\n\treg [511:0] X0;\n\treg [511:0] X1;\n\twire [511:0] X0in;\n\twire [511:0] X1in;\n\twire [511:0] X0out;\n\treg [1023:0] salsaShiftReg;\n\treg [31:0] nonce_sr;\t\t\t// In series with salsaShiftReg\n\tassign dout = salsaShiftReg[1023:1024-SBITS];\n\n\t// sstate is implemented in ram (alternatively could use a rotating shift register)\n\treg [THREADS_BITS+30:0] sstate [THREADS-1:0];\t\t// NB initialized via a long reset (see pbkdfengine)\n\t// List components of sstate here for ease of maintenance ...\n\twire [2:0] mstate_in;\n\twire [10:0] cycle_in;\n\twire [9:0] writeaddr_in;\n\twire doneROM_in;\n\twire addrsourceMix_in;\n\twire addrsourceSave_in;\n\twire [THREADS_BITS+1:0] intcycles_in;\t\t\t\t// How many do we need? Say THREADS_BITS+1\n\n\twire [9:0] writeaddr_next = writeaddr_in + 10'd1;\n\n\treg [31:0] snonce [THREADS-1:0];\t\t\t\t\t// Nonce store. Note bidirectional loading below, this will either implement\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// as registers or dual-port ram, so do NOT integrate with sstate.\n\t\n\t// NB no busy_in or result_in as these flag are NOT saved on a per-thread basis\n\n\t// Convert salsaShiftReg to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = salsaShiftReg[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\tend\n\tendgenerate\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of RAM size\n\t(* S = \"TRUE\" *) reg [9:0] writeaddr = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\twire [9:0] Xaddr;\n\twire [ADDRBITS-1:0]rd_addr;\n\twire [ADDRBITS-1:0]wr_addr1;\n\twire [ADDRBITS-1:0]wr_addr2;\n\twire [ADDRBITS-1:0]wr_addr3;\n\twire [ADDRBITS-1:0]wr_addr4;\n\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\t(* S = \"TRUE\" *) reg ram_wren = 1'b0;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\t// Top ram address is reserved for X0Save/X1save, so adjust\n\t\n\twire [15:0] memtop = 16'hfffe;\t// One less than the top memory location (per THREAD bank)\n\t\n\twire [ADDRBITS-THREADS_BITS-1:0] adj_addr;\n\n\tif (ADDRBITS < 13)\n\t\tassign adj_addr = (Xaddr[9:THREADS_BITS+10-ADDRBITS] == memtop[9:THREADS_BITS+10-ADDRBITS]) ?\n\t\t\t\t\t\t\tmemtop[ADDRBITS-THREADS_BITS-1:0] : Xaddr[9:THREADS_BITS+10-ADDRBITS];\n\telse\n\t\tassign adj_addr = Xaddr;\n\t\n\twire [THREADS_BITS-1:0] phase_addr;\n\tassign phase_addr = phase[THREADS_BITS-1:0];\n\n\t// TODO can we remove the +1 and adjust the wr_addr to use the same prefix via phase_d?\n\tassign rd_addr = { phase_addr+1, addrsourceSave_in ? memtop[ADDRBITS-THREADS_BITS:1] : adj_addr };\t// LSB are ignored\n\t\t\n\twire [9:0] writeaddr_adj = addrsourceMix ? memtop[10:1] : writeaddr;\n\t\n\tassign wr_addr1 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\tassign wr_addr2 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\tassign wr_addr3 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\tassign wr_addr4 = { phase_addr, writeaddr_adj[9:THREADS_BITS+10-ADDRBITS] };\n\n\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_1 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_2 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_3 = 0;\n\t(* S = \"TRUE\" *) reg [ADDRBITS-1:0] rd_addr_z_4 = 0;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr1 = rd_addr | rd_addr_z_1;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr2 = rd_addr | rd_addr_z_2;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr3 = rd_addr | rd_addr_z_3;\n\t(* S = \"TRUE\" *) wire [ADDRBITS-1:0] rd_addr4 = rd_addr | rd_addr_z_4;\n\t\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (rd_addr1, wr_addr1, ram_clk, ram1_din, ram_wren, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (rd_addr2, wr_addr2, ram_clk, ram2_din, ram_wren, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (rd_addr3, wr_addr3, ram_clk, ram3_din, ram_wren, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (rd_addr4, wr_addr4, ram_clk, ram4_din, ram_wren, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = datasourceLoad ? X : { Xmix, X0out};\t// Registered input\n\t\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, X0, X1, Xmix, X0out, Xaddr);\n\n\t// Main multiplexer\n\twire [511:0] Zbits;\n\tassign Zbits = {512{xoren}};\t\t// xoren enables xor from ram (else we load from ram)\n\t\n\t// With luck the synthesizer will interpret this correctly as one-hot control ...\n\n\t// DEBUG using default state of 0 for XSnull so as to show up issues with preserved values (previously held value X0/X1)\n\t// assign X0in = (XCtl==XSmix) ? X0out : (XCtl==XSram) ? (X0out & Zbits) ^ ramout[511:0] : (XCtl==XSload) ? X[511:0] : 0;\n\t// assign X1in = (XCtl==XSmix) ? Xmix : (XCtl==XSram) ? (Xmix & Zbits) ^ ramout[1023:512] : (XCtl==XSload) ? X[1023:512] : 0;\n\t\n\t// Now using explicit control signals (rather than relying on synthesizer to map correctly)\n\t// XSMix is now the default (XSnull is unused as this mapped onto zero in the DEBUG version above) - TODO amend FSM accordingly\n\tassign X0in =  XCtl[2] ? (X0out & Zbits) ^ ramout[511:0] : XCtl[0] ? X[511:0] : X0out;\n\tassign X1in =  XCtl[2] ? (Xmix & Zbits) ^ ramout[1023:512] : XCtl[0] ? X[1023:512] : Xmix;\n\n\t// Salsa FSM - TODO may want to move this into a separate function (for floorplanning), see hashvariant-C\n\n\t// Hold separate state for each thread (a bit of a kludge to avoid rewriting FSM from scratch)\n\t// NB must ensure shift and result do NOT overlap by carefully controlling timing of start signal\n\t// NB Phase has THREADS+1 cycles, but we do not save the state for (phase==THREADS) as it is never active\n\n\tassign { mstate_in, writeaddr_in, cycle_in, doneROM_in, addrsourceMix_in, addrsourceSave_in, intcycles_in} =\n\t\t\t\t(phase == THREADS ) ? 0 : sstate[phase];\t\n\t\n\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\n\treg busy_flag = 1'b0;\n\t\n`ifdef ONETHREAD\n\t// TEST CONTROLLER ... just allow a single thread to run (busy is currently a common flag)\n\t// NB the thread automatically restarts after it completes, so its a slight misnomer to say it starts once.\n\treg start_once = 1'b0;\n\twire start_flag;\n\tassign start_flag = fsmstart & ~start_once;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine\n`else\n\t// NB start_flag only has effect when a thread is at R_IDLE, ie after reset, normally a thread will automatically\n\t// restart on completion. We need to spread the R_IDLE starts evenly to ensure proper ooperation. NB the pbkdf\n\t// engine requires busy and result, but this  looks alter itself in the salsa FSM, even though these are global\n\t// flags. Reset periodically (on loadnonce in pbkdfengine) to ensure it stays in sync.\n\treg [15:0] start_count = 0;\n\t// TODO automatic configuration (currently assumes THREADS 8 or 16, and ADDRBITS 12,11,10 calculated as follows...)\n\t// For THREADS=8, lookup_gap=2 salsa takes on average 9*(1024+(1024*1.5)) = 23040 clocks, generically 9*1024*(lookup_gap/2+1.5)\n\t// For THREADS=16, use 17*1024*(lookup_gap/2+1.5), where lookupgap is double that for THREADS=8\n\tparameter START_INTERVAL = (THREADS==16) ?\t((ADDRBITS==12) ? 60928 : (ADDRBITS==11) ? 95744 : 165376) / THREADS :\t// 16 threads\n\t\t\t\t\t\t\t\t\t\t\t\t((ADDRBITS==12) ? 23040 : (ADDRBITS==11) ? 36864 :  50688) / THREADS ;\t//  8 threads\n\treg start_flag = 1'b0;\n\tassign busy = busy_flag;\t\t// Ack to pbkdfengine - this will toggle on transtion through R_START\n`endif\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tX0 <= X0in;\n\t\tX1 <= X1in;\n\t\t\n\t\tif (phase_d != THREADS)\n\t\t\tsstate[phase_d] <= fsmreset ? 0 : { mstate, writeaddr, cycle, doneROM, addrsourceMix, addrsourceSave, intcycles };\n\n\t\tmstate <= mstate_in;\t\t// Set defaults (overridden below as necessary)\n\t\twriteaddr <= writeaddr_in;\n\t\tcycle <= cycle_in;\n\t\tintcycles <= intcycles_in;\n\t\tdoneROM <= doneROM_in;\n\t\taddrsourceMix <= addrsourceMix_in;\n\t\taddrsourceSave <= addrsourceSave_in;\t\t// Overwritten below, but addrsourceSave_in is used above\n\t\t\n\t\t// Duplicate address to reduce fanout (its a ridiculous kludge, but seems to be the approved method)\n\t\trd_addr_z_1 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_2 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_3 <= {ADDRBITS{fsmreset}};\n\t\trd_addr_z_4 <= {ADDRBITS{fsmreset}};\n\t\t\n\t\tXCtl <= XSnull;\t\t\t\t// Default states\n\t\taddrsourceSave <= 0;\t\t// NB addrsourceSave_in is the active control so this DOES need to be in sstate\n\t\tdatasourceLoad <= 0;\t\t// Does not need to be saved in sstate\n\t\tresultsourceRam <= 0;\t\t// Does not need to be saved in sstate\n\t\tram_wren <= 0;\n\t\txoren <= 1;\n\t\t\n\t\t// Interface FSM ensures threads start evenly (required for correct salsa FSM operation)\n\t\t`ifdef ONETHREAD\n\t\tif (fsmstart && phase!=THREADS)\n\t\t\tstart_once <= 1'b1;\n\t\tif (fsmreset)\n\t\t\tstart_once <= 1'b0;\n\t\t`else\n\t\tstart_count <= start_count + 1;\n\t\t// start_flag <= 1'b0;\t\t\t// Done below when we transition out of R_IDLE\n\t\tif (fsmreset || start_count == START_INTERVAL)\n\t\tbegin\n\t\t\tstart_count <= 0;\n\t\t\tif (~fsmreset && fsmstart)\n\t\t\t\tstart_flag <= 1'b1;\n\t\tend\n\t\t`endif\n\t\t\n\t\t// Could use explicit mux for this ...\n\t\tif (shift)\n\t\tbegin\n\t\t\tsalsaShiftReg <= { salsaShiftReg[1023-SBITS:0], nonce_sr[31:32-SBITS] };\n\t\t\tnonce_sr <= { nonce_sr[31-SBITS:0], din};\n\t\tend\n\t\telse\n\t\tif (XCtl==XSload && phase_d != THREADS)\t\t// Set at end of previous hash - this is executed regardless of phase\t\t\n\t\tbegin\n\t\t\tsalsaShiftReg <= resultsourceRam ? ramout : { Xmix, X0out };\t// Simultaneously with XSload\n\t\t\tnonce_sr <= snonce[phase_d];\t\t\t\t\t\t\t\t\t// NB bidirectional load\n\t\t\tsnonce[phase_d] <= nonce_sr;\n\t\tend\n\t\t\n\t\tif (fsmreset == 1'b1)\n\t\tbegin\n\t\t\tmstate <= R_IDLE;\t\t// This will propagate to all sstate slots as we hold reset for 10 cycles\n\t\t\tbusy_flag <= 1'b0;\n\t\t\tresult <= 1'b0;\n\t\tend\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate_in)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\t// R_IDLE only applies after reset. Normally each thread will reenter at S_START and\n\t\t\t\t\t// assumes that input data is waiting (this relies on the threads being started evenly,\n\t\t\t\t\t// hence the interface FSM at the top of this file)\n\t\t\t\t\tif (phase!=THREADS && start_flag)\t// Ensure (phase==THREADS) slot is never active\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSload;\t\t\t// First time only (normally done at end of previous salsa cycle=1023)\n\t\t\t\t\t\t`ifndef ONETHREAD\n\t\t\t\t\t\t\tstart_flag <= 1'b0;\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t\t// Toggle the busy flag low to ack pbkdfengine (its usually already set\n\t\t\t\t\t\t\t\t\t\t\t\t// since other threads are running)\n\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\tdatasourceLoad <= 1'b1;\n\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tmstate <= R_START;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_START: begin\t\t\t\t\t\t// Reentry point after thread completion. ASSUMES new data is ready.\n\t\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\t\twriteaddr <= writeaddr_next;\n\t\t\t\t\t\tcycle <= 0;\n\t\t\t\t\t\tif (ADDRBITS == 13)\n\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Full scratchpad needs to write to addr=001 next cycle\n\t\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\t\tbusy_flag <= 1'b1;\n\t\t\t\t\t\tresult <= 1'b0;\n\t\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\t\tend\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\twriteaddr <= writeaddr_next;\n\t\t\t\t\tif (writeaddr_in==1022)\n\t\t\t\t\t\tdoneROM <= 1'b1;\t\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\telse\n\t\t\t\t\tif (~doneROM_in)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\t\tram_wren <= ~|writeaddr_next[THREADS_BITS+9-ADDRBITSX:0];\t// Only write non-interpolated addresses\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\tend\n\t\t\t\t\t\n\t\t\t\t\tif (doneROM_in)\n\t\t\t\t\tbegin\n\t\t\t\t\t\taddrsourceMix <= 1'b1;\t\t// Remains set for duration of R_MIX\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t// Need this to cover the case of the initial read being interpolated\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_MIX\n\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\tif ( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:THREADS_BITS+10-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr[THREADS_BITS+9-ADDRBITSX:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[THREADS_BITS+9-ADDRBITSX:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\tcycle <= cycle_in + 11'd1;\n\t\t\t\t\tif (cycle_in==1023)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tbusy_flag <= 1'b0;\t// Will hold at 0 for 9 clocks until set at R_START\n\t\t\t\t\t\tif (fsmstart)\t\t\t// Check data input is ready\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXCtl <= XSload;\t\t// Initial load else we overwrite input NB This is\n\t\t\t\t\t\t\t\t\t\t\t\t// executed on the next cycle, regardless of phase\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\tmstate <= R_START;\t\t// Restart immediately\n\t\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\t\tdatasourceLoad <= 1'b1;\n\t\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// mstate <= R_IDLE;\t\t// Wait for start_flag\n\t\t\t\t\t\t\tmstate <= R_WAIT;\n\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Save result\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t\t// Load from ram next cycle\n\t\t\t\t\t\t// NB CODE IS REPLICATED IN R_WRITE\n\t\t\t\t\t\tif (ADDRBITS < 13)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+12-ADDRBITSX{1'b0}}, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\t// Interpolated addresses\n\n\t\t\t\t\t\t\tif ( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\t\t\t// Highest address reserved\n\t\t\t\t\t\t\t\tintcycles <= { {THREADS_BITS+11-ADDRBITSX{1'b0}}, 1'b1, Xaddr[THREADS_BITS+9-ADDRBITSX:0] };\n\n\t\t\t\t\t\t\tif ( (Xaddr[9:THREADS_BITS+10-ADDRBITSX] == memtop[ADDRBITSX-THREADS_BITS:1]) || |Xaddr[THREADS_BITS+9-ADDRBITSX:0] )\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\t\t\txoren <= 0;\t\t\t\t\t\t// Will do direct load from ram, not xor\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t\t\t\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\t// If intcycles will be set to 1, need to preset for readback\n\t\t\t\t\t\t\tif ( \n\t\t\t\t\t\t\t\t( Xaddr[THREADS_BITS+9-ADDRBITSX:0] == 1 ) &&\n\t\t\t\t\t\t\t\t!( Xaddr[9:THREADS_BITS+10-ADDRBITSX] ==  memtop[ADDRBITSX-THREADS_BITS:1] )\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\t\tend\n\t\t\t\t\t\t// END REPLICATED BLOCK\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\tR_WAIT: begin\n\t\t\t\t\t\tif (fsmstart)\t\t\t// Check data input is ready\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tXCtl <= XSload;\t\t// Initial load else we overwrite input NB This is\n\t\t\t\t\t\t\t\t\t\t\t\t// executed on the next cycle, regardless of phase\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\tresult <= 1'b1;\n\t\t\t\t\t\t\tmstate <= R_START;\t\t// Restart immediately\n\t\t\t\t\t\t\twriteaddr <= 0;\t\t\t// Preset to write X on next cycle\n\t\t\t\t\t\t\tdatasourceLoad <= 1'b1;\n\t\t\t\t\t\t\tresultsourceRam <= 1'b1;\n\t\t\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data (9 clocks later)\n\t\t\t\tend\n\t\t\t\t\n\t\t\t\tR_INT: begin\n\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\tXCtl <= XSmix;\t\t\t\t\t\t\t\n\t\t\t\t\tintcycles <= intcycles_in - 1;\n\t\t\t\t\tif (intcycles_in==2)\n\t\t\t\t\t\taddrsourceSave <= 1'b1;\t// Preset to read saved data (9 clocks later)\n\t\t\t\t\tif (intcycles_in==1)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSram;\t\t\t// Setup to XOR from saved X0/X1 in ram at next cycle\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\tend\n\t\t\t\t\t// Else mstate remains at R_INT so we continue interpolating\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (mstate==R_MIX)\n\t\t$display (\"phase %d cycle %d Xmix %08x\\n\", phase, cycle-1, Xmix[511:480]);\n`endif\n\tend\t// always @(posedge hash_clk)\nendmodule"
  },
  {
    "path": "experimental/Ztex-1-15y/sha-256-functions.v",
    "content": "/*\n*\n* Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n*\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n\n`timescale 1ns/1ps\n\nmodule e0 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y = {x[1:0],x[31:2]} ^ {x[12:0],x[31:13]} ^ {x[21:0],x[31:22]};\n\nendmodule\n\n\nmodule e1 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y = {x[5:0],x[31:6]} ^ {x[10:0],x[31:11]} ^ {x[24:0],x[31:25]};\n\nendmodule\n\n\nmodule ch (x, y, z, o);\n\n\tinput [31:0] x, y, z;\n\toutput [31:0] o;\n\n\tassign o = z ^ (x & (y ^ z));\n\nendmodule\n\n\nmodule maj (x, y, z, o);\n\n\tinput [31:0] x, y, z;\n\toutput [31:0] o;\n\n\tassign o = (x & y) | (z & (x | y));\n\nendmodule\n\n\nmodule s0 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y[31:29] = x[6:4] ^ x[17:15];\n\tassign y[28:0] = {x[3:0], x[31:7]} ^ {x[14:0],x[31:18]} ^ x[31:3];\n\nendmodule\n\n\nmodule s1 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y[31:22] = x[16:7] ^ x[18:9];\n\tassign y[21:0] = {x[6:0],x[31:17]} ^ {x[8:0],x[31:19]} ^ x[31:10];\n\nendmodule\n\n\n"
  },
  {
    "path": "experimental/Ztex-1-15y/sha256_transform.v",
    "content": "/*\n*\n* Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n*\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n\n`timescale 1ns/1ps\n\n// A quick define to help index 32-bit words inside a larger register.\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\n// Perform a SHA-256 transformation on the given 512-bit data, and 256-bit\n// initial state,\n// Outputs one 256-bit hash every LOOP cycle(s).\n//\n// The LOOP parameter determines both the size and speed of this module.\n// A value of 1 implies a fully unrolled SHA-256 calculation spanning 64 round\n// modules and calculating a full SHA-256 hash every clock cycle. A value of\n// 2 implies a half-unrolled loop, with 32 round modules and calculating\n// a full hash in 2 clock cycles. And so forth.\n\nmodule sha256_transform #(\n\tparameter LOOP = 7'd64\t\t// For ltcminer\n) (\n\tinput clk,\n\tinput feedback,\n\tinput [5:0] cnt,\n\tinput [255:0] rx_state,\n\tinput [511:0] rx_input,\n\toutput reg [255:0] tx_hash\n);\n\n\t// Constants defined by the SHA-2 standard.\n\tlocalparam Ks = {\n\t\t32'h428a2f98, 32'h71374491, 32'hb5c0fbcf, 32'he9b5dba5,\n\t\t32'h3956c25b, 32'h59f111f1, 32'h923f82a4, 32'hab1c5ed5,\n\t\t32'hd807aa98, 32'h12835b01, 32'h243185be, 32'h550c7dc3,\n\t\t32'h72be5d74, 32'h80deb1fe, 32'h9bdc06a7, 32'hc19bf174,\n\t\t32'he49b69c1, 32'hefbe4786, 32'h0fc19dc6, 32'h240ca1cc,\n\t\t32'h2de92c6f, 32'h4a7484aa, 32'h5cb0a9dc, 32'h76f988da,\n\t\t32'h983e5152, 32'ha831c66d, 32'hb00327c8, 32'hbf597fc7,\n\t\t32'hc6e00bf3, 32'hd5a79147, 32'h06ca6351, 32'h14292967,\n\t\t32'h27b70a85, 32'h2e1b2138, 32'h4d2c6dfc, 32'h53380d13,\n\t\t32'h650a7354, 32'h766a0abb, 32'h81c2c92e, 32'h92722c85,\n\t\t32'ha2bfe8a1, 32'ha81a664b, 32'hc24b8b70, 32'hc76c51a3,\n\t\t32'hd192e819, 32'hd6990624, 32'hf40e3585, 32'h106aa070,\n\t\t32'h19a4c116, 32'h1e376c08, 32'h2748774c, 32'h34b0bcb5,\n\t\t32'h391c0cb3, 32'h4ed8aa4a, 32'h5b9cca4f, 32'h682e6ff3,\n\t\t32'h748f82ee, 32'h78a5636f, 32'h84c87814, 32'h8cc70208,\n\t\t32'h90befffa, 32'ha4506ceb, 32'hbef9a3f7, 32'hc67178f2};\n\n\n\tgenvar i;\n\n\tgenerate\n\n\t\tfor (i = 0; i < 64/LOOP; i = i + 1) begin : HASHERS\n\t\t\t// These are declared as registers in sha256_digester\n\t\t\twire [511:0] W;\t\t\t// reg tx_w\n\t\t\twire [255:0] state;\t\t// reg tx_state\n\n\t\t\tif(i == 0)\n\t\t\t\tsha256_digester U (\n\t\t\t\t\t.clk(clk),\n\t\t\t\t\t.k(Ks[32*(63-cnt) +: 32]),\n\t\t\t\t\t.rx_w(feedback ? W : rx_input),\n\t\t\t\t\t.rx_state(feedback ? state : rx_state),\n\t\t\t\t\t.tx_w(W),\n\t\t\t\t\t.tx_state(state)\n\t\t\t\t);\n\t\t\telse\n\t\t\t\tsha256_digester U (\n\t\t\t\t\t.clk(clk),\n\t\t\t\t\t.k(Ks[32*(63-LOOP*i-cnt) +: 32]),\n\t\t\t\t\t.rx_w(feedback ? W : HASHERS[i-1].W),\n\t\t\t\t\t.rx_state(feedback ? state : HASHERS[i-1].state),\n\t\t\t\t\t.tx_w(W),\n\t\t\t\t\t.tx_state(state)\n\t\t\t\t);\n\t\tend\n\n\tendgenerate\n\n\talways @ (posedge clk)\n\tbegin\n\t\tif (!feedback)\n\t\tbegin\n\t\t\ttx_hash[`IDX(0)] <= rx_state[`IDX(0)] + HASHERS[64/LOOP-6'd1].state[`IDX(0)];\n\t\t\ttx_hash[`IDX(1)] <= rx_state[`IDX(1)] + HASHERS[64/LOOP-6'd1].state[`IDX(1)];\n\t\t\ttx_hash[`IDX(2)] <= rx_state[`IDX(2)] + HASHERS[64/LOOP-6'd1].state[`IDX(2)];\n\t\t\ttx_hash[`IDX(3)] <= rx_state[`IDX(3)] + HASHERS[64/LOOP-6'd1].state[`IDX(3)];\n\t\t\ttx_hash[`IDX(4)] <= rx_state[`IDX(4)] + HASHERS[64/LOOP-6'd1].state[`IDX(4)];\n\t\t\ttx_hash[`IDX(5)] <= rx_state[`IDX(5)] + HASHERS[64/LOOP-6'd1].state[`IDX(5)];\n\t\t\ttx_hash[`IDX(6)] <= rx_state[`IDX(6)] + HASHERS[64/LOOP-6'd1].state[`IDX(6)];\n\t\t\ttx_hash[`IDX(7)] <= rx_state[`IDX(7)] + HASHERS[64/LOOP-6'd1].state[`IDX(7)];\n\t\tend\n\tend\n\n\nendmodule\n\n\nmodule sha256_digester (clk, k, rx_w, rx_state, tx_w, tx_state);\n\n\tinput clk;\n\tinput [31:0] k;\n\tinput [511:0] rx_w;\n\tinput [255:0] rx_state;\n\n\toutput reg [511:0] tx_w;\n\toutput reg [255:0] tx_state;\n\n\n\twire [31:0] e0_w, e1_w, ch_w, maj_w, s0_w, s1_w;\n\n\n\te0\te0_blk\t(rx_state[`IDX(0)], e0_w);\n\te1\te1_blk\t(rx_state[`IDX(4)], e1_w);\n\tch\tch_blk\t(rx_state[`IDX(4)], rx_state[`IDX(5)], rx_state[`IDX(6)], ch_w);\n\tmaj\tmaj_blk\t(rx_state[`IDX(0)], rx_state[`IDX(1)], rx_state[`IDX(2)], maj_w);\n\ts0\ts0_blk\t(rx_w[63:32], s0_w);\n\ts1\ts1_blk\t(rx_w[479:448], s1_w);\n\n\twire [31:0] t1 = rx_state[`IDX(7)] + e1_w + ch_w + rx_w[31:0] + k;\n\twire [31:0] t2 = e0_w + maj_w;\n\twire [31:0] new_w = s1_w + rx_w[319:288] + s0_w + rx_w[31:0];\n\t\n\n\talways @ (posedge clk)\n\tbegin\n\t\ttx_w[511:480] <= new_w;\n\t\ttx_w[479:0] <= rx_w[511:32];\n\n\t\ttx_state[`IDX(7)] <= rx_state[`IDX(6)];\n\t\ttx_state[`IDX(6)] <= rx_state[`IDX(5)];\n\t\ttx_state[`IDX(5)] <= rx_state[`IDX(4)];\n\t\ttx_state[`IDX(4)] <= rx_state[`IDX(3)] + t1;\n\t\ttx_state[`IDX(3)] <= rx_state[`IDX(2)];\n\t\ttx_state[`IDX(2)] <= rx_state[`IDX(1)];\n\t\ttx_state[`IDX(1)] <= rx_state[`IDX(0)];\n\t\ttx_state[`IDX(0)] <= t1 + t2;\n\tend\n\nendmodule\n"
  },
  {
    "path": "experimental/Ztex-1-15y/test_miner.v",
    "content": "// Testbench\n\n`timescale 1ns/1ps\n\n`ifdef SIM\t\t\t\t\t// Avoids wrong top selected if included in ISE/PlanAhead sources\nmodule test_miner ();\n\n\treg clk = 1'b0;\n\treg reset = 1'b0, select = 1'b0;\n\treg [31:0] cycle = 32'd0;\n\n\tinitial begin\n\t\tclk = 0;\n\t\t\n\t\twhile(1)\n\t\tbegin\n\t\t\t#5 clk = 1; #5 clk = 0;\n\t\tend\n\tend\n\n\talways @ (posedge clk)\n\tbegin\n\t\tcycle <= cycle + 32'd1;\n\n\t\t// Do a reset to toggle phase\n\t\tif (cycle == 100)\n\t\t\tselect <= 1;\n\t\tif (cycle == 101)\n\t\t\treset <= 1;\n\t\tif (cycle == 102)\n\t\t\treset <= 0;\n\t\tif (cycle == 103)\n\t\t\tselect <= 0;\n\n\tend\n\n\twire [7:0] write;\n\tztex_ufm1_15y1 uut (clk, reset,  select,  1'b0,  1'b0,  1'b0,  1'b0,  1'b0,  1'b0,  1'b0,  1'b0,  8'd0,  write);\nendmodule\n`endif"
  },
  {
    "path": "experimental/Ztex-1-15y/xilinx_ram.v",
    "content": "// xilinx_ram.v - inferring the ram seems to work fine\n\nmodule ram # ( parameter ADDRBITS=10 ) (\n\traddr,\n\twaddr,\n\tclock,\n\tdata,\n\twren,\n\tq);\n\n\tinput\t[ADDRBITS-1:0]  raddr;\n\tinput\t[ADDRBITS-1:0]  waddr;\n\tinput\t  clock;\n\tinput\t[255:0]  data;\n\tinput\t  wren;\n\toutput\t[255:0]  q;\n\n\t//synthesis attribute ram_style of store is block\n\treg [255:0] store [(2 << (ADDRBITS-1))-1:0];\n\treg[ADDRBITS-1:0] raddr_reg;\n\t\n\talways @ (posedge clock)\n\tbegin\n\t\traddr_reg <= raddr;\n\t\tif (wren)\n\t\t\tstore[waddr] <= data;\n\tend\n\t\n\tassign q = store[raddr_reg];\n\t\t\t\nendmodule"
  },
  {
    "path": "experimental/Ztex-1-15y/ztex_ufm1_15y.ucf",
    "content": "NET \"fxclk_in\"  LOC = \"L22\" | IOSTANDARD = LVCMOS33;\n# NET \"fxclk_in\" TNM_NET = \"fxclk_in\";\n# TIMESPEC \"TS_fxclk_in\" = PERIOD \"fxclk_in\" 20.3ns HIGH 50 %;\n\nNET \"clk\"  TNM_NET = \"clk\";\n# Single core ...\nTIMESPEC \"TS_clk\" = PERIOD \"clk\" 46MHz HIGH 50 %;\n\nNET \"select\"  LOC = \"AB11\" | IOSTANDARD = LVCMOS33 ;\n\n# input\nNET \"write<0>\"  LOC = \"Y17\" | IOSTANDARD = LVCMOS33 | DRIVE = 12; # PB0\nNET \"write<1>\"  LOC = \"V13\" | IOSTANDARD = LVCMOS33 | DRIVE = 12; # PB1\nNET \"write<2>\"  LOC = \"W13\" | IOSTANDARD = LVCMOS33 | DRIVE = 12; # PB2\nNET \"write<3>\"  LOC = \"AA8\" | IOSTANDARD = LVCMOS33 | DRIVE = 12; # PB3\nNET \"write<4>\"  LOC = \"AB8\" | IOSTANDARD = LVCMOS33 | DRIVE = 12; # PB4\nNET \"write<5>\"  LOC = \"W6\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;  # PB5\nNET \"write<6>\"  LOC = \"Y6\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;  # PB6\nNET \"write<7>\"  LOC = \"Y9\" | IOSTANDARD = LVCMOS33 | DRIVE = 12;  # PB7\n\nNET \"wr_clk\"  LOC = \"AA22\" | IOSTANDARD = LVCMOS33;       # PA0\nNET \"wr_start\" LOC = \"AB17\" | IOSTANDARD = LVCMOS33 ;     # PA7\n\n# dcm\nNET \"dcm_progclk\"  LOC = \"U15\" | IOSTANDARD = LVCMOS33 ;  # PA2\nNET \"dcm_progdata\"  LOC = \"AB21\" | IOSTANDARD = LVCMOS33 ; # PA4\nNET \"dcm_progen\"  LOC = \"Y18\" | IOSTANDARD = LVCMOS33 ;   # PA5\n\n#output\nNET \"read<0>\"  LOC = \"V21\" | IOSTANDARD = LVCMOS33 ;  # PD0\nNET \"read<1>\"  LOC = \"V22\" | IOSTANDARD = LVCMOS33 ;  # PD1\nNET \"read<2>\"  LOC = \"U20\" | IOSTANDARD = LVCMOS33 ;  # PD2\nNET \"read<3>\"  LOC = \"U22\" | IOSTANDARD = LVCMOS33 ;  # PD3\nNET \"read<4>\"  LOC = \"R20\" | IOSTANDARD = LVCMOS33 ;  # PD4\nNET \"read<5>\"  LOC = \"R22\" | IOSTANDARD = LVCMOS33 ;  # PD5\nNET \"read<6>\"  LOC = \"P18\" | IOSTANDARD = LVCMOS33 ;  # PD6\nNET \"read<7>\"  LOC = \"P19\" | IOSTANDARD = LVCMOS33 ;  # PD7\n\nNET \"reset\"  LOC = \"G20\" | IOSTANDARD = LVCMOS33 ;     # PC0\nNET \"rd_clk\"  LOC = \"H19\" | IOSTANDARD = LVCMOS33 ;    # PC6\nNET \"pll_stop\"  LOC = \"H20\" | IOSTANDARD = LVCMOS33 ;  # PC5\nNET \"clk_reset\"  LOC = \"G19\" | IOSTANDARD = LVCMOS33 ; # PC4\n\n# unused\n#NET \"\"  LOC = \"AB9\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;  # PC3\n#NET \"\"  LOC = \"H18\" | IOSTANDARD = LVCMOS33 | DRIVE = 12 ;  # PC7\n\n# TIG's\nNET \"inbuf[*]\" TIG;\n# NET \"m/golden_nonce[*]\" TIG;\nNET \"select\" TIG;\nPIN \"select\" TIG;\n\n"
  },
  {
    "path": "experimental/Ztex-1-15y/ztex_ufm1_15y1.v",
    "content": "/*!\n   btcminer -- BTCMiner for ZTEX USB-FPGA Modules: HDL code for ZTEX USB-FPGA Module 1.15b (one double hash pipe)\n   Copyright (C) 2012 ZTEX GmbH\n   http://www.ztex.de\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License version 3 as\n   published by the Free Software Foundation.\n\n   This program is distributed in the hope that it will be useful, but\n   WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n   General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, see http://www.gnu.org/licenses/.\n!*/\n\nmodule ztex_ufm1_15y1 (fxclk_in, reset, select, clk_reset, pll_stop,  dcm_progclk, dcm_progdata, dcm_progen,  rd_clk, wr_clk, wr_start, read, write);\n\n\tinput fxclk_in, select, reset, clk_reset, pll_stop, dcm_progclk, dcm_progdata, dcm_progen, rd_clk, wr_clk, wr_start;\n\tinput [7:0] read;\n\toutput [7:0] write;\n\n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2()\n\t\tinput integer value;\n\t\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\t\tend\n\tendfunction\n\n// Configure cores here since using `ifdef rather than generate (lazy)\n//`define DUALCORE\t\t\t\t\t// Comment out for single core (actually performs better)\n//`define PROTOCOL80\t\t\t\t// Select 80 or 76 byte protocol (NB use 76 for current cgminer)\n\n`ifdef DUALCORE\n\tlocalparam LOCAL_MINERS = 2;\t// One or two cores (configures ADDRBITS automatically)\n`else\n\tlocalparam LOCAL_MINERS = 1;\t// One or two cores (configures ADDRBITS automatically)\n`endif\n\n\tlocalparam ADDRBITS = 12 - clog2(LOCAL_MINERS);\t// Automatically selects largest RAM that will fit LX150\n\tlocalparam SBITS = 8;\t\t// Shift data path width\n\n`ifdef DUALCORE\n\treg  phase = 1'b0;\n`endif\n\n\treg [3:0] rd_clk_b, wr_clk_b;\n\treg wr_start_b1 = 0, wr_start_b2 = 0, reset_buf = 0, reset_buf_d = 0, clk_reset_buf = 1, pll_stop_buf = 1, select_buf = 0;\n\treg dcm_progclk_buf, dcm_progdata_buf, dcm_progen_buf;\n\treg [4:0] wr_delay;\n\treg [127:0] outbuf;\n\treg [7:0] read_buf, write_buf;\n\treg [31:0] golden_nonce_a = 32'd0, golden_nonce_b = 32'd0;\n\t\n\twire fxclk, clk, dcm_clk, pll_fb, pll_clk0, dcm_locked, pll_reset;\n\twire [2:1] dcm_status;\n\twire [31:0] golden_nonce_1, hash_1;\n\twire [31:0] golden_nonce_2, hash_2;\n\twire [31:0] golden_nonce, nonce_a, hash_a;\n\twire gn_match_1, gn_match_2;\n\t\n`define NOPLL\t\t// PLL does not route so workaround uses DCM only\n`ifndef SIM\n\tIBUFG bufg_fxclk (\n          .I(fxclk_in),\n          .O(fxclk)\n        );\n\n`ifndef NOPLL\n\tBUFG bufg_clk (\n          .I(pll_clk0),\n          .O(clk)\n        );\n`else\n\tBUFGCE bufg_clk (\n          .I(dcm_clk),\n          .CE(~pll_reset),\n          .O(clk)\n        );\n`endif\n\n\t\tDCM_CLKGEN #(\n\t\t\t.CLKFX_DIVIDE(4),\n\t\t\t.CLKFX_MULTIPLY(16),\t\t// Will be 32 or higher when set dynamically\n\t\t\t// .CLKFXDV_DIVIDE(8),\t\t// NB using CLKFXDV output (original version up to v03)\n\t\t\t.CLKFXDV_DIVIDE(4),\t\t\t// Single core can run faster, but firmware limit is 248Mhz so double it at v04\n\t\t\t\t\t\t\t\t\t\t// CARE cgminer clock now needs to be 124MHz or thereabouts instead of 248MHz\n\t\t\t.CLKIN_PERIOD(20.8333)\t\t// 48MHz input\n\t\t) \n\t\tdcm0 (\n\t\t\t.CLKIN(fxclk),\n\t\t\t.CLKFXDV(dcm_clk),\n\t\t\t.FREEZEDCM(1'b0),\n\t\t\t.PROGCLK(dcm_progclk_buf),\n\t\t\t.PROGDATA(dcm_progdata_buf),\n\t\t\t.PROGEN(dcm_progen_buf),\n\t\t\t.LOCKED(dcm_locked),\n\t\t\t.STATUS(dcm_status),\n\t\t\t.RST(clk_reset_buf)\n\t\t);\n\n`ifndef NOPLL\n\tPLL_BASE #(\n\t\t\t.BANDWIDTH(\"LOW\"),\n\t\t\t.CLKFBOUT_MULT(4),\n\t\t\t.CLKOUT0_DIVIDE(4),\n\t\t\t.CLKOUT0_DUTY_CYCLE(0.5),\n\t\t\t.CLK_FEEDBACK(\"CLKFBOUT\"), \n\t\t\t.COMPENSATION(\"INTERNAL\"),\n\t\t\t.DIVCLK_DIVIDE(1),\n\t\t\t.REF_JITTER(0.10),\n\t\t\t.CLKIN_PERIOD(5.2),\t\t\t// Needed since UCF now constrains clk rather than fxclk\n\t\t\t.RESET_ON_LOSS_OF_LOCK(\"FALSE\")\n\t\t)\n\t\tpll0 (\n\t\t\t.CLKFBOUT(pll_fb),\n\t\t\t.CLKOUT0(pll_clk0),\n\t\t\t.CLKFBIN(pll_fb),\n\t\t\t.CLKIN(dcm_clk),\n\t\t\t.RST(pll_reset)\n\t\t);\n`endif\n\n`else\n\tassign clk = fxclk_in;\t// SIM\n`endif\n\n\tassign write = select ? write_buf : 8'bz;\t\t// This actually does tristate the outputs\n\tassign pll_reset = pll_stop_buf | ~dcm_locked | clk_reset_buf | dcm_status[2];\n\n`ifdef SIM\n\t\t// Test hash - final hash at 672,780ns\n`ifdef PROTOCOL80\n\t\t// 80 byte protocol includes nonce\n\t\treg [639:0] inbuf_tmp = {\n\t\t\t128'h0000318f7e71441b141fe951b2b0c7df,\n\t\t\t256'hc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af755756,\n\t\t\t256'h18e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000\n\t\t\t};\n`else\n\t// 76 byte protocol excludes nonce\n\t\treg [607:0] inbuf_tmp = {\n\t\t\t96'h7e71441b141fe951b2b0c7df,\n\t\t\t256'hc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af755756,\n\t\t\t256'h18e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000\n\t\t\t};\n`endif\t\t\t\t\n`else\t// SIM\n`ifdef PROTOCOL80\n\t\treg [639:0] inbuf_tmp;\n`else\n\t\treg [639:0] inbuf_tmp;\n`endif\t\t\t\t\n`endif\t// SIM\n\n`ifdef PROTOCOL80\n\treg [639:0] inbuf;\t\t\t// 80 byte protocol\n`else\n\treg [607:0] inbuf;\t\t\t// 76 byte protocol\n`endif\t\t\t\t\n\n\twire [31:0] mod_target = 32'h00007fff;\t\t\t// Hard coded for diff=2\n\twire [255:0] data1 = inbuf[255:0];\n\twire [255:0] data2 = inbuf[511:256];\n\n`ifdef PROTOCOL80\n\twire [127:0] data3 = inbuf[639:512];\n`else\n`ifdef SIM\n\twire [127:0] data3 = { 32'h0000318f, inbuf[607:512] };\n`else\n\twire [127:0] data3 = { 32'd0, inbuf[607:512] };\n`endif\t\t\t\t\n`endif\t\t\n\n\t// Generate loadnonce strobe for new work (NB this initiates a full engine reset)\n\treg loadnonce = 1'b0;\t// Strobe generated loading work\n\treg loadnonce_d = 1'b0;\t// Delay by one since extra register stage inbuf\n\t\n\t// NB For now using same clk for both P and S\n\n\twire [31:0] nonce_out_1;\n\twire salsa_busy_1, salsa_result_1, salsa_reset_1, salsa_start_1, salsa_shift_1;\n\twire [SBITS-1:0] salsa_din_1;\n\twire [SBITS-1:0] salsa_dout_1;\n\n\tpbkdfengine #(.SBITS(SBITS)) P1\n\t\t(.hash_clk(clk), .pbkdf_clk(clk), .data1(data1), .data2(data2), .data3(data3), .target(mod_target),\n\t\t.nonce_msb( 4'd0 ), .nonce_out(nonce_out_1), .golden_nonce_out(golden_nonce_1),\n\t\t.golden_nonce_match(gn_match_1), .loadnonce(loadnonce_d),\n\t\t.salsa_din(salsa_din_1), .salsa_dout(salsa_dout_1), .salsa_busy(salsa_busy_1), .salsa_result(salsa_result_1),\n\t\t.salsa_reset(salsa_reset_1), .salsa_start(salsa_start_1), .salsa_shift(salsa_shift_1), .hash_out(hash_1));\n\n\tsalsaengine #(.ADDRBITS(ADDRBITS), .SBITS(SBITS)) S1\n\t\t(.hash_clk(clk), .reset(salsa_reset_1), .din(salsa_din_1), .dout(salsa_dout_1),\n\t\t.shift(salsa_shift_1), .start(salsa_start_1), .busy(salsa_busy_1), .result(salsa_result_1) );\n\n`ifdef DUALCORE\n\twire [31:0] nonce_out_2;\n\twire salsa_busy_2, salsa_result_2, salsa_reset_2, salsa_start_2, salsa_shift_2;\n\twire [SBITS-1:0] salsa_din_2;\n\twire [SBITS-1:0] salsa_dout_2;\n\n\tpbkdfengine #(.SBITS(SBITS)) P2\n\t\t(.hash_clk(clk), .pbkdf_clk(clk), .data1(data1), .data2(data2), .data3(data3), .target(mod_target),\n\t\t.nonce_msb( 4'd8 ), .nonce_out(nonce_out_2), .golden_nonce_out(golden_nonce_2),\n\t\t.golden_nonce_match(gn_match_2), .loadnonce(loadnonce_d),\n\t\t.salsa_din(salsa_din_2), .salsa_dout(salsa_dout_2), .salsa_busy(salsa_busy_2), .salsa_result(salsa_result_2),\n\t\t.salsa_reset(salsa_reset_2), .salsa_start(salsa_start_2), .salsa_shift(salsa_shift_2), .hash_out(hash_2));\n\n\tsalsaengine #(.ADDRBITS(ADDRBITS), .SBITS(SBITS)) S2\n\t\t(.hash_clk(clk), .reset(salsa_reset_2), .din(salsa_din_2), .dout(salsa_dout_2),\n\t\t.shift(salsa_shift_2), .start(salsa_start_2), .busy(salsa_busy_2), .result(salsa_result_2) );\n\n\t// Need to alternate between cores to ensure HW error monitoring works correctly in driver_ztex\n\t// Phase toggles on reset which occurs prior to each new work\n\n\tassign nonce_a = phase ? nonce_out_2 : nonce_out_1;\n\tassign hash_a = phase ? hash_2 : hash_1;\n\tassign gn_match = gn_match_1 | gn_match_2;\n\tassign golden_nonce = gn_match_1 ? golden_nonce_1 : golden_nonce_2;\n`else\n\t// Single core\n\tassign nonce_a = nonce_out_1;\n\tassign hash_a = hash_1;\n\tassign gn_match = gn_match_1;\n\tassign golden_nonce = golden_nonce_1;\n`endif\n\t\n\talways @ (posedge clk)\n\tbegin\n\t\tloadnonce <= 1'b0;\t\t\t\t\t\t\t\t// For pbkdfengine\n\t\tloadnonce_d <= loadnonce;\t\t\t\t\t\t// Delay by one since extra register stage inbuf\n\n\t\t// KRAMBLE not sure I understand this, it does not seem to be conventional clock-crossing as the comparison is the wrong\n\t\t// end of the shift register, so perhaps its a de-bounce on the rd_clk (which is sort of clock-crossing too) ??\n\t\tif ( (rd_clk_b[3] == rd_clk_b[2]) && (rd_clk_b[2] == rd_clk_b[1]) && (rd_clk_b[1] != rd_clk_b[0]) && select_buf )\n\t\tbegin\n`ifdef PROTOCOL80\n\t\t    inbuf_tmp[639:632] <= read_buf;\n\t\t    inbuf_tmp[631:0] <= inbuf_tmp[639:8];\n`else\n\t\t    inbuf_tmp[607:600] <= read_buf;\n\t\t    inbuf_tmp[599:0] <= inbuf_tmp[607:8];\n`endif\n\t\t\t// Nonce will be loaded (or reset to 0 in 76 byte protocol) every byte since there is no signal\n\t\t\t// that indicates when work is completely loaded (this means hashes generated during loading\n\t\t\t// are invalid, so we also reset golden_nonce_a/b below)\n\t\t\tloadnonce <= 1'b1;\t\t\t\t\t\t\t// For pbkdfengine (single clock cycle strobe)\n\t\tend\n\t\tinbuf <= inbuf_tmp;  // due to TIG's\n\t\t    \n\t\tif ( wr_start_b1 && wr_start_b2 )\n\t\tbegin\n   \t\t    wr_delay <= 5'd0;\n\t\tend else \n\t\tbegin\n\t\t    wr_delay[0] <= 1'b1;\n\t\t    wr_delay[4:1] <= wr_delay[3:0];\n\t\tend\n\t\t\n\t\tif ( ! wr_delay[4] ) \n\t\tbegin\n   \t\t    outbuf <= { golden_nonce_b, hash_a, nonce_a, golden_nonce_a };\n   \t\tend else\n   \t\tbegin\n\t\t\t// KRAMBLE see note above for rd_clk\n\t\t    if ( (wr_clk_b[3] == wr_clk_b[2]) && (wr_clk_b[2] == wr_clk_b[1]) && (wr_clk_b[1] != wr_clk_b[0]) ) \n\t\t\toutbuf[119:0] <= outbuf[127:8];\n   \t\tend\n\n   \t\tif ( reset_buf | loadnonce )\t\t\t\t\t// Also reset on loadnonce since hashes are invalid\n   \t\tbegin\n   \t\t    golden_nonce_a <= 32'd0;\n   \t\t    golden_nonce_b <= 32'd0;\n   \t\tend else if ( gn_match ) \n   \t\tbegin\n   \t\t    golden_nonce_b <= golden_nonce_a;\n   \t\t    golden_nonce_a <= golden_nonce;\n   \t\tend\n\n\t\tread_buf <= read;\n\t\twrite_buf <= outbuf[7:0];\n\n\t\trd_clk_b[0] <= rd_clk;\n\t\trd_clk_b[3:1] <= rd_clk_b[2:0];\n\n\t\twr_clk_b[0] <= wr_clk;\n\t\twr_clk_b[3:1] <= wr_clk_b[2:0];\n\n\t\twr_start_b1 <= wr_start;\n\t\twr_start_b2 <= wr_start_b1;\n\t\t\n\t\tselect_buf <= select;\n\t\tif ( select ) \n\t\tbegin\n\t\t    reset_buf <= reset;\n\t\tend\n\n\t\treset_buf_d <= reset_buf;\n\t\tif (reset_buf_d & ~reset_buf)\t\t\t\t\t// Executes on trailing edge of reset\n\t\tbegin\n`ifdef DUALCORE\n\t\t\tphase <= ~phase;\n`endif\n\t\tend\n\tend\n\n\talways @ (posedge fxclk)\n\tbegin\n\t\tdcm_progclk_buf <= dcm_progclk;\n\t\tdcm_progdata_buf <= dcm_progdata;\n\t\tdcm_progen_buf <= dcm_progen & select;\n\t\tif ( select ) \n\t\tbegin\n\t\t    clk_reset_buf <= clk_reset;\n\t\t    pll_stop_buf <= pll_stop;\n\t\tend\n\tend\n\n\nendmodule\n\n"
  },
  {
    "path": "experimental/hashvariant-A.v",
    "content": "/* hashvariant-A.v - uses RAM to reduce register count by eliminating X0Save, X1Save\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n\nNB This version requires HALFRAM to be set ... TODO Get it working with full scratchpad\n\nhashvariant-A.v uses RAM to reduce register count by eliminating X0Save, X1Save\nThere are a lot of other registers that could be eliminated, eg XBuf and MixOut\ncould be moved into RAM, leaving X0,X1 as a single general purpose accumulator.\nThis would prevent pipelining of the PBKDF2_SHA256 operations with the Salsa Mix\nbut may be useful in reducing LE count (though since registers come almost \"free\"\nthe main effect would be from any reduction of LE's used for multiplexing).\n\n25MHz build FMAX 24.57 MHz 85C/Slow\n\n+-------------------------------------------------------------------------------+\n; Flow Summary                                                                  ;\n+------------------------------------+------------------------------------------+\n; Flow Status                        ; Successful - Wed Aug 07 18:36:45 2013    ;\n; Quartus II Version                 ; 10.1 Build 153 11/29/2010 SJ Web Edition ;\n; Revision Name                      ; ltcminer                                 ;\n; Top-level Entity Name              ; ltcminer                                 ;\n; Family                             ; Cyclone IV E                             ;\n; Device                             ; EP4CE22F17C6                             ;\n; Timing Models                      ; Final                                    ;\n; Total logic elements               ; 16,470 / 22,320 ( 74 % )                 ;\n;     Total combinational functions  ; 14,166 / 22,320 ( 63 % )                 ;\n;     Dedicated logic registers      ; 8,685 / 22,320 ( 39 % )                  ;\n; Total registers                    ; 8685                                     ;\n; Total pins                         ; 9 / 154 ( 6 % )                          ;\n; Total virtual pins                 ; 0                                        ;\n; Total memory bits                  ; 524,288 / 608,256 ( 86 % )               ;\n; Embedded Multiplier 9-bit elements ; 0 / 132 ( 0 % )                          ;\n; Total PLLs                         ; 1 / 4 ( 25 % )                           ;\n+------------------------------------+------------------------------------------+\n\nCompare with the version 3 code ...\n+-------------------------------------------------------------------------------+\n; Flow Summary                                                                  ;\n+------------------------------------+------------------------------------------+\n; Flow Status                        ; Successful - Sat Aug 03 11:30:38 2013    ;\n; Quartus II Version                 ; 10.1 Build 153 11/29/2010 SJ Web Edition ;\n; Revision Name                      ; ltcminer                                 ;\n; Top-level Entity Name              ; ltcminer                                 ;\n; Family                             ; Cyclone IV E                             ;\n; Device                             ; EP4CE22F17C6                             ;\n; Timing Models                      ; Final                                    ;\n; Total logic elements               ; 17,272 / 22,320 ( 77 % )                 ;\n;     Total combinational functions  ; 15,175 / 22,320 ( 68 % )                 ;\n;     Dedicated logic registers      ; 9,707 / 22,320 ( 43 % )                  ;\n; Total registers                    ; 9707                                     ;\n; Total pins                         ; 9 / 154 ( 6 % )                          ;\n; Total virtual pins                 ; 0                                        ;\n; Total memory bits                  ; 524,288 / 608,256 ( 86 % )               ;\n; Embedded Multiplier 9-bit elements ; 0 / 132 ( 0 % )                          ;\n; Total PLLs                         ; 1 / 4 ( 25 % )                           ;\n+------------------------------------+------------------------------------------+\n\n*/\n\n// NB HALFRAM is currently REQUIRED for this variant ... TODO Get it working for full scratchpad\n`define HALFRAM\n\t\n`timescale 1ns/1ps\n\nmodule hashcore (hash_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce);\n\n\tinput hash_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\t\t// Supports multicore (set MULTICORE below)\n\toutput [31:0] nonce_out;\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\t\n\treg poweron_reset = 1'b1;\n\treg reset = 1'b1;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tpoweron_reset <= 1'b0;\n\t\treset <= poweron_reset;\t\t\t// Ensures a full clock cycle for reset\n\tend\n\t\n\treg [31:0] nonce_prevous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\n\t`ifndef NOMULTICORE\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\tassign nonce_out = nonce;\n\n\treg [31:0] nonce_1 = 32'd0;\t\t// Pipeline nonce since needed for final PBKDF2_SHA256_80_128_32\n\treg [31:0] nonce_2 = 32'd0;\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [31:0] blockcnt = 32'd0;\t// Takes values 1..4 for block iteration (NB could hardwire top 29 bits)\n\treg [1023:0] Xbuf = 1024'd0;\n\treg [1023:0] MixOut;\t\t\t// Salsa mixer ouput\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\t\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(hash_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\n\t// These flags control the interaction of the SHA256 and SalsaMix FSM's. While OK in simulation\n\t// Altera Quartus II barfs on synthesis, hence the ugly hack.\n\t\n\t// Original version ...\n\t// reg SMixInRdy = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\t// reg SMixOutRdy = 1'b0;\t\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\n\t// Ugly hack...\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\treg Clr_SMixInRdy = 1'b0;\n\treg Set_SMixOutRdy = 1'b0;\n\treg Clr_SMixOutRdy = 1'b0;\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\tend\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\t\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz). I don't even pretend to\n\t// understand how it works so please excuse any naive implimentation errors.\n\t\n\t// NB apparently this is poor coding style (sorry, I'm just a newbie here), but its working so\n\t// I'm not going to change it now (perhaps in a future version). It could also do with optimisation\n\t// though its not essential as the SHA256 does not limit the overall throughput.\n\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_XX=22,\t\t\t\t\t\t\t\t\t\t\t\t// Possibly superfluous (go straight to S_IDLE)\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\t\t\n\t\tif (reset == 1'b1)\n\t\t\tstate <= S_IDLE;\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tif (SMixOutRdy ||\t// Process output\n\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\tbegin\n\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\tblockcnt <= 32'd1;\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_2 : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tblockcnt, nonce, data3[95:0] };\n\t\t\t\t\t\tblockcnt <= blockcnt + 1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\n\t\t\t\tS_B6: begin\t// Shift output into X buffer from MSB->LSB\n\t\t\t\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\t\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\t\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\t\t\t\tXbuf[1023:768] <= tx_hash;\n\t\t\t\t\t\t// NB nonce is incremented in SMIX FSM\n\n\t\t\t\t\t\tif (blockcnt == 5)\n\t\t\t\t\t\t\tstate <= S_XX;\t// Done\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\tblockcnt, nonce, data3[95:0] };\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_XX: begin\n\t\t\t\t\t\t// State is possibly superfluous (go straight to S_IDLE from S_B6)\n\t\t\t\t\t\t// SMixInRdy <= 1;\t\t// Original\n\t\t\t\t\t\tSet_SMixInRdy <= 1;\t// Ugly hack\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\tend\n\t\t\t\t\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_2;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n\tend\n\n\t// Convert Xbuf to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = Xbuf[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\n\t\t// Also need to do MixOut\n\t\twire [31:0] mix;\n\t\tassign mix = MixOut[`IDX(i)];\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\t// NB apparently this is poor coding style (sorry, I'm just a newbie here), but its working so\n\t// I'm not going to change it now (perhaps in a future version). It could also do with optimisation\n\t// as this IS on the critical path for throughput, unlike SHA256. It may be possible to remove some\n\t// latency for significant performance boost. SPECIFICALLY it may be possible to use 4 cycles rather\n\t// than 5 per write, and similarily for R_MIX\n\n\tparameter R_IDLE=0, R_WRITE=1, R_MIX=2, R_INT=3;\n\treg [1:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg [5:0] mcount = 5'd0;\t// Salsa latency\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs. Maybe rename doneWRITE?\n\treg mixfeedback = 1'b0;\n\treg addrsourceMix = 1'b0;\t// Another HACK\n\treg addrsourceSave = 1'b0;\n\n\treg [511:0] X0;\n\treg [511:0] X1;\n\n\t// Use the highest ram address to save old value during interpolation\n\t// wire [511:0] X0Save;\t\t\t// Now wires (were reg), now UNUSED\n\t// wire [511:0] X1Save;\n\treg\t [1:0] intcycles = 2'b0;\t// Number of interpolation cycles required\n\t\n\twire [511:0] Xmix;\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of HALFRAM mode\n\treg [9:0] writeaddr = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\t`ifdef HALFRAM\n\t\tparameter ADDRBITS = 9;\n\t`else\n\t\tparameter ADDRBITS = 10;\n\t`endif\n\n\twire [ADDRBITS-1:0]ram_addr;\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\treg ram_wren;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\t`ifdef HALFRAM\n\t\t// This is the half scratchpad version\n\t\t// Top ram address is reserved for X0Save, so adjust\n\t\twire [8:0] adj_addr = (Xmix[9:1] == 9'h1ff) ? 9'h1fe : Xmix[9:1];\n\t\tassign ram_addr = addrsourceMix ? (addrsourceSave ? 9'h1ff : adj_addr) : writeaddr[9:1];\t// LSB is ignored\n\t`else\n\t\t// This is the full scratchpad version\n\t\twire [9:0] adj_addr = (Xmix[9:0] == 10'h3ff) ? 10'h3fe : Xmix[9:0];\n\t\tassign ram_addr = addrsourceMix ? (addrsourceSave ? 10'h3ff : adj_addr) : writeaddr;\n\t`endif\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (ram_addr, ram_clk, ram1_din, ram_wren, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (ram_addr, ram_clk, ram2_din, ram_wren, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (ram_addr, ram_clk, ram3_din, ram_wren, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (ram_addr, ram_clk, ram4_din, ram_wren, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = { X1, X0} ;\t// Registered input\n\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, mixfeedback, X0, X1, Xmix);\n\n\t// Salsa FSM (see note above about bad coding style)\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tram_wren <= 0;\t\t\t\t\t\t\t// Default state, overriden below in R_WRITE and R_MIX\n\t\taddrsourceSave <= 0;\n\t\tSet_SMixOutRdy <= 1'b0;\n\t\tClr_SMixInRdy <= 1'b0;\n\t\tif (loadnonce || (nonce_prevous_load != data3[127:96]))\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_prevous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\tnonce_prevous_load <= data3[127:96];\n\t\tend\n\t\tif (reset == 1'b1)\n\t\t\tmstate <= R_IDLE;\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\twriteaddr <= 0;\n\t\t\t\t\tmcount <= 0;\n\t\t\t\t\tX0 <= X[511:0];\n\t\t\t\t\tX1 <= X[1023:512];\n\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\tif (SMixInRdy)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Initial write cycle\n\t\t\t\t\t\t\t// SMixInRdy <= 0;\t\t// Original version\n\t\t\t\t\t\t\tClr_SMixInRdy <= 1;\t\t// Ugly hack\n\t\t\t\t\t\t\t// Save and increment nonce (NB done here not in SHA256 FSM)\n\t\t\t\t\t\t\tnonce_1 <= nonce;\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 28'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 32'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\tmcount <= mcount + 6'd1;\n\t\t\t\t\t// 8 stages since salsa takes 4 clock cycles. NB This minimises clock cycles, but adds to\n\t\t\t\t\t// the propagation delay in the salsa. The alternative of adding a cycle or two of latency to\n\t\t\t\t\t// reduce propagation delay is SLOWER due to the extra clocks needed.\n\t\t\t\t\t// Write to ROM every 2nd cycle (NB we are writing previous data here)\n\t\t\t\t\t// NB One extra cycle is performed after ROM is complete to update X0,X1 to inital state for R_MIX\n\t\t\t\t\tif (mcount==0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\t\tif (writeaddr==1023)\n\t\t\t\t\t\t\tdoneROM <= 1'b1;\t\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\t\twriteaddr <= writeaddr + 10'd1;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount==4)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount == 3 || mcount == 7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tX0 <= X1;\n\t\t\t\t\t\tX1 <= Xmix;\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount == 6 && doneROM)\t\t\t// NASTY HACK ... preset the address source one cycle early\n\t\t\t\t\t\taddrsourceMix <= 1'b1;\n\t\t\t\t\tif (mcount == 7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tif (doneROM)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tcycle <= 0;\n\t\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\t\t// Need this to cover the case of the initial read being interpolated\n\t\t\t\t\t\t\tintcycles <= { 1'b0, Xmix[0] };\t\t// Flag odd addresses (for use in next cycle due to ram latency)\n\t\t\t\t\t\t\tif ( Xmix[9:1] == 9'h1ff )\t\t\t// Highest ram address is reserved for X0save, so\n\t\t\t\t\t\t\t\tintcycles <= { 1'b1, Xmix[0] };\t// need up to 3 interpolations\n\n\t\t\t\t\t\t\tif ( (Xmix[9:1] == 9'h1ff) || Xmix[0])\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t\t// Setup to save at mcount==0 (also does so entering R_IDLE\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t\t// after cycle==1023 but of no consequence)\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// NB the !doneROM test is superfluous here as its in the else clause of if(doneROM)\n\t\t\t\t\t\t\t`ifdef HALFRAM\n\t\t\t\t\t\t\t\tif (!doneROM && !writeaddr[0])\t// Do not write on odd cycles (half scratchpad)\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Since registered we preset this here\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tif (!doneROM)\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Since registered we preset this here\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// Entered with mixfeedback == 0 (set at mcount==7 above)\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\t// The longest chain is from mixfeedback to ram address input (since XMix is not registered),\n\t\t\t\t\t// again as noted above, extra register stages would simply reduce throughput.\n\t\t\t\t\tmcount <= mcount + 5'd1;\n\t\t\t\t\tif (mcount == 0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\t`ifdef HALFRAM\n\t\t\t\t\t\t\tif (intcycles != 0)\t\t\t// Set in previous cycle\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\t// The following flags need to be set one cycle earlier so moved to mcount==8\n\t\t\t\t\t\t\t\t// TODO ALSO set on final stage of R_WRITE if required\n\t\t\t\t\t\t\t\t// addrsourceSave <= 1'b1;\t// Write save data from X0,X1 to ram\n\t\t\t\t\t\t\t\t// ram_wren <= 1'b1;\n\t\t\t\t\t\t\t\t// X0Save <= X0;\t\t// Now saved to ram\n\t\t\t\t\t\t\t\t// X1Save <= X1;\n\t\t\t\t\t\t\t\tX0 <= ramout[511:0];\n\t\t\t\t\t\t\t\tX1 <= ramout[1023:512];\n\t\t\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\t// Perhaps we can reuse the xor's in the salsa module here?\n\t\t\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\t\t\tX0 <= X0 ^ ramout[511:0];\n\t\t\t\t\t\t\t\tX1 <= X1 ^ ramout[1023:512];\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t// Perhaps we can reuse the xor's in the salsa module here?\n\t\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\t\t X0 <= X0 ^ ramout[511:0];\n\t\t\t\t\t\t\t X1 <= X1 ^ ramout[1023:512];\n\t\t\t\t\t\t`endif\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount==1 || mcount==5)\n\t\t\t\t\t\tmixfeedback <= 1;\n\t\t\t\t\tif (mcount == 4 || mcount == 8)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\tX0 <= X1;\n\t\t\t\t\t\tX1 <= Xmix;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount == 8)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tcycle <= cycle + 11'd1;\n\t\t\t\t\t\tif (cycle == 1023)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// Pipeline the result so we can start processing the next X input\n\t\t\t\t\t\t\tMixOut <= { Xmix, X1 };\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\t// SMixOutRdy <= 1'b1;\t\t// Original version\n\t\t\t\t\t\t\tSet_SMixOutRdy <= 1'b1;\t\t// Ugly hack\n\t\t\t\t\t\t\tnonce_2 <= nonce_1;\n\t\t\t\t\t\t\tmstate <= R_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\t\t\t`ifdef HALFRAM\t\t\t\t\t\t\t// TODO make this work for full scratchpad\n\t\t\t\t\t\t\t// ALSO do this in final step of R_WRITE\n\t\t\t\t\t\t\tintcycles <= { 1'b0, Xmix[0] };\t\t// Flag odd addresses (for use in next cycle due to ram latency)\n\t\t\t\t\t\t\tif ( Xmix[9:1] == 9'h1ff )\t\t\t// Highest ram address is reserved for X0save, so\n\t\t\t\t\t\t\t\tintcycles <= { 1'b1, Xmix[0] };\t// need up to 3 interpolations\n\n\t\t\t\t\t\t\tif ( (Xmix[9:1] == 9'h1ff) || Xmix[0])\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t\t// Setup to save at mcount==0 (also does so entering R_IDLE\n\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t\t// after cycle==1023 but of no consequence)\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t`endif\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t// Always need interpolation, even with full scratchpad since top address is reserved for X0Save\n\t\t\t\tR_INT: begin\n\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\t// Mcount has already been incremented in R_MIX\n\t\t\t\t\tmcount <= mcount + 6'd1;\n\t\t\t\t\tif (mcount==1 || mcount==5)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount == 4)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 0;\n\t\t\t\t\t\tX0 <= X1;\n\t\t\t\t\t\tX1 <= Xmix;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount == 6)\n\t\t\t\t\t\taddrsourceSave <= 1'b1;\t\t// Preset to read saved data at mcount==8\n\t\t\t\t\tif (mcount == 8)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 0; // Required\n\t\t\t\t\t\t// X0 <= X1 ^ X0Save;\t\t// Same result as step 0 in R_MIX\n\t\t\t\t\t\t// X1 <= Xmix ^ X1Save;\n\t\t\t\t\t\tmcount <= 1;\t\t// Skip 0 since done above\n\t\t\t\t\t\tintcycles <= intcycles - 1;\n\t\t\t\t\t\tif (intcycles == 1)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tX0 <= X1 ^ ramout[511:0];\t// Ram contains saved data\n\t\t\t\t\t\t\tX1 <= Xmix ^ ramout[1023:512];\n\t\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tX0 <= X1;\n\t\t\t\t\t\t\tX1 <= Xmix;\n\t\t\t\t\t\t\t// mstate remains at R_INT so we continue interpolating\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n`ifdef SIM\n/*\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (mstate == R_MIX && mcount == 8)\n\t\t$display (\"cycle %d Xmix %08x\\n\", cycle, Xmix[511:480]);\n*/\n`endif\n\tend\t// always @(posedge hash_clk)\nendmodule"
  },
  {
    "path": "experimental/hashvariant-B.v",
    "content": "/* hashvariant-B.v needs salsa-B.v - pipelined 2x clock speed (NOT interleaving hashes, that will be hashvariant-C)\n\nFinal hash and golden_nonce_match are at 362,080 nS\n\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n//`define HALFRAM\t\t// SET this to target DE0-Nano (in quartus assignments/settings/verilog hdl)\n\t\n`timescale 1ns/1ps\n\nmodule hashcore (hash_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce);\n\n\tinput hash_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\t\t// Supports multicore (set MULTICORE below)\n\toutput [31:0] nonce_out;\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\t\n\treg poweron_reset = 1'b1;\n\treg reset = 1'b1;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tpoweron_reset <= 1'b0;\n\t\treset <= poweron_reset;\t\t\t// Ensures a full clock cycle for reset\n\tend\n\t\n\treg [31:0] nonce_prevous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\n\t`ifndef NOMULTICORE\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\tassign nonce_out = nonce;\n\n\treg [31:0] nonce_1 = 32'd0;\t\t// Pipeline nonce since needed for final PBKDF2_SHA256_80_128_32\n\treg [31:0] nonce_2 = 32'd0;\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [31:0] blockcnt = 32'd0;\t// Takes values 1..4 for block iteration (NB could hardwire top 29 bits)\n\treg [1023:0] Xbuf = 1024'd0;\n\treg [1023:0] MixOut;\t\t\t// Salsa mixer ouput\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\t\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(hash_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\n\t// These flags control the interaction of the SHA256 and SalsaMix FSM's. While OK in simulation\n\t// Altera Quartus II barfs on synthesis, hence the ugly hack.\n\t\n\t// Original version ...\n\t// reg SMixInRdy = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\t// reg SMixOutRdy = 1'b0;\t\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\n\t// Ugly hack...\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\treg Clr_SMixInRdy = 1'b0;\n\treg Set_SMixOutRdy = 1'b0;\n\treg Clr_SMixOutRdy = 1'b0;\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\tend\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\t\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz). I don't even pretend to\n\t// understand how it works so please excuse any naive implimentation errors.\n\t\n\t// NB apparently this is poor coding style (sorry, I'm just a newbie here), but its working so\n\t// I'm not going to change it now (perhaps in a future version). It could also do with optimisation\n\t// though its not essential as the SHA256 does not limit the overall throughput.\n\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_XX=22,\t\t\t\t\t\t\t\t\t\t\t\t// Possibly superfluous (go straight to S_IDLE)\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\t\t\n\t\tif (reset == 1'b1)\n\t\t\tstate <= S_IDLE;\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tif (SMixOutRdy ||\t// Process output\n\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\tbegin\n\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\tblockcnt <= 32'd1;\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_2 : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tblockcnt, nonce, data3[95:0] };\n\t\t\t\t\t\tblockcnt <= blockcnt + 1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\n\t\t\t\tS_B6: begin\t// Shift output into X buffer from MSB->LSB\n\t\t\t\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\t\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\t\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\t\t\t\tXbuf[1023:768] <= tx_hash;\n\t\t\t\t\t\t// NB nonce is incremented in SMIX FSM\n\n\t\t\t\t\t\tif (blockcnt == 5)\n\t\t\t\t\t\t\tstate <= S_XX;\t// Done\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\tblockcnt, nonce, data3[95:0] };\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_XX: begin\n\t\t\t\t\t\t// State is possibly superfluous (go straight to S_IDLE from S_B6)\n\t\t\t\t\t\t// SMixInRdy <= 1;\t\t// Original\n\t\t\t\t\t\tSet_SMixInRdy <= 1;\t// Ugly hack\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\tend\n\t\t\t\t\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_2;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n\tend\n\n\t// Convert Xbuf to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = Xbuf[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\n\t\t// Also need to do MixOut\n\t\twire [31:0] mix;\n\t\tassign mix = MixOut[`IDX(i)];\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\t// NB apparently this is poor coding style (sorry, I'm just a newbie here), but its working so\n\t// I'm not going to change it now (perhaps in a future version). It could also do with optimisation\n\t// as this IS on the critical path for throughput, unlike SHA256. It may be possible to remove some\n\t// latency for significant performance boost. SPECIFICALLY it may be possible to use 4 cycles rather\n\t// than 5 per write, and similarily for R_MIX\n\n\tparameter R_IDLE=0, R_WRITE=1, R_MIX=2, R_INT=3;\n\treg [1:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg [6:0] mcount = 6'd0;\t// Salsa latency\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs. Maybe rename doneWRITE?\n\treg mixfeedback = 1'b0;\n\treg addrsourceMix = 1'b0;\t// Another HACK\n\n\treg [511:0] X0;\n\treg [511:0] X1;\n\t`ifdef HALFRAM\n\t\treg [511:0] X0Save;\t\t// Save old value during interpolation\n\t\treg [511:0] X1Save;\n\t\treg\toddAddr = 1'b0;\t\t// Flag for odd addresses to interpolate\n\t`endif\n\twire [511:0] Xmix;\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of HALFRAM mode\n\treg [9:0] writeaddr = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\t`ifdef HALFRAM\n\t\tparameter ADDRBITS = 9;\n\t`else\n\t\tparameter ADDRBITS = 10;\n\t`endif\n\n\twire [ADDRBITS-1:0]ram_addr;\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\treg ram_wren = 1'b0;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\treg [9:0] Xmixd = 10'b0;\n\talways @ (posedge hash_clk)\n\t\tXmixd <= Xmix[9:0];\t\t// Extra delay for hashvariant-B mix\n\t\t\n\t`ifdef HALFRAM\n\t\t// This is the half scratchpad version\n\t\tassign ram_addr = addrsourceMix ? Xmixd[9:1] : writeaddr[9:1];\t// LSB is ignored\n\t`else\n\t\t// This is the full scratchpad version\n\t\tassign ram_addr = addrsourceMix ? Xmixd[9:0] : writeaddr;\n\t`endif\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (ram_addr, ram_clk, ram1_din, ram_wren, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (ram_addr, ram_clk, ram2_din, ram_wren, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (ram_addr, ram_clk, ram3_din, ram_wren, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (ram_addr, ram_clk, ram4_din, ram_wren, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = { X1, X0} ;\t// Registered input\n\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, mixfeedback, X0, X1, Xmix);\n\n\t// Salsa FSM (see note above about bad coding style)\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tSet_SMixOutRdy <= 1'b0;\n\t\tClr_SMixInRdy <= 1'b0;\n\t\t`ifdef HALFRAM\n\t\t\toddAddr <= Xmix[0];\t\t// Flag odd addresses (for use in next cycle due to ram latency)\n\t\t`endif\n\t\tif (loadnonce || (nonce_prevous_load != data3[127:96]))\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_prevous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\tnonce_prevous_load <= data3[127:96];\n\t\tend\n\t\tif (reset == 1'b1)\n\t\t\tmstate <= R_IDLE;\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\twriteaddr <= 0;\n\t\t\t\t\tmcount <= 0;\n\t\t\t\t\tX0 <= X[511:0];\n\t\t\t\t\tX1 <= X[1023:512];\n\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\tif (SMixInRdy)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Initial write cycle\n\t\t\t\t\t\t\t// SMixInRdy <= 0;\t\t// Original version\n\t\t\t\t\t\t\tClr_SMixInRdy <= 1;\t\t// Ugly hack\n\t\t\t\t\t\t\t// Save and increment nonce (NB done here not in SHA256 FSM)\n\t\t\t\t\t\t\tnonce_1 <= nonce;\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 28'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 32'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\tmcount <= mcount + 6'd1;\n\t\t\t\t\tram_wren <= 0;\t\t// Default state, overriden below at mcount==9\n\t\t\t\t\t// 8 stages since salsa takes 4 clock cycles. NB This minimises clock cycles, but adds to\n\t\t\t\t\t// the propagation delay in the salsa. The alternative of adding a cycle or two of latency to\n\t\t\t\t\t// reduce propagation delay is SLOWER due to the extra clocks needed.\n\t\t\t\t\t// Write to ROM every 2nd cycle (NB we are writing previous data here)\n\t\t\t\t\t// NB One extra cycle is performed after ROM is complete to update X0,X1 to inital state for R_MIX\n\t\t\t\t\tif (mcount==0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\t\tif (writeaddr==1023)\n\t\t\t\t\t\t\tdoneROM <= 1'b1;\t\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\t\twriteaddr <= writeaddr + 10'd1;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount==8)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount == 7 || mcount == 15)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tX0 <= X1;\n\t\t\t\t\t\tX1 <= Xmix;\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount == 14 && doneROM)\t\t\t// NASTY HACK ... preset the address source one cycle early\n\t\t\t\t\t\taddrsourceMix <= 1'b1;\n\t\t\t\t\tif (mcount == 15)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tif (doneROM)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tcycle <= 0;\n\t\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// NB the !doneROM test is superfluous here as its in the else clause of if(doneROM)\n\t\t\t\t\t\t\t`ifdef HALFRAM\n\t\t\t\t\t\t\t\tif (!doneROM && !writeaddr[0])\t// Do not write on odd cycles (half scratchpad)\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Since registered we preset this here\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tif (!doneROM)\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Since registered we preset this here\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// Entered with mixfeedback == 0 (set at mcount==7 above)\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\t// The longest chain is from mixfeedback to ram address input (since XMix is not registered),\n\t\t\t\t\t// again as noted above, extra register stages would simply reduce throughput.\n\t\t\t\t\t// NB hashvariant-B adds an extra delay to ram address to give correct timing since\n\t\t\t\t\t// there is a double ram cycle (needed to keep pipeline even).\n\t\t\t\t\tmcount <= mcount + 6'd1;\n\t\t\t\t\tif (mcount == 1)\t\t\t\t// 1 not 0 in hashvariant-B (see above)\n\t\t\t\t\tbegin\n\t\t\t\t\t\t`ifdef HALFRAM\n\t\t\t\t\t\t\tif (oddAddr)\t\t\t// Set in previous cycle\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tX0Save <= X0;\n\t\t\t\t\t\t\t\tX0 <= ramout[511:0];\n\t\t\t\t\t\t\t\tX1Save <= X1;\n\t\t\t\t\t\t\t\tX1 <= ramout[1023:512];\n\t\t\t\t\t\t\t\tmixfeedback <= 0;\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\t// Perhaps we can reuse the xor's in the salsa module here?\n\t\t\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\t\t\tX0 <= X0 ^ ramout[511:0];\n\t\t\t\t\t\t\t\tX1 <= X1 ^ ramout[1023:512];\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t// Perhaps we can reuse the xor's in the salsa module here?\n\t\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\t\t X0 <= X0 ^ ramout[511:0];\n\t\t\t\t\t\t\t X1 <= X1 ^ ramout[1023:512];\n\t\t\t\t\t\t`endif\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount==2 || mcount==10)\n\t\t\t\t\t\tmixfeedback <= 1;\n\t\t\t\t\tif (mcount == 9 || mcount == 17)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\tX0 <= X1;\n\t\t\t\t\t\tX1 <= Xmix;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount == 17)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tcycle <= cycle + 11'd1;\n\t\t\t\t\t\tif (cycle == 1023)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// Pipeline the result so we can start processing the next X input\n\t\t\t\t\t\t\tMixOut <= { Xmix, X1 };\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\t// SMixOutRdy <= 1'b1;\t\t// Original version\n\t\t\t\t\t\t\tSet_SMixOutRdy <= 1'b1;\t\t// Ugly hack\n\t\t\t\t\t\t\tnonce_2 <= nonce_1;\n\t\t\t\t\t\t\tmstate <= R_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t`ifdef HALFRAM\n\t\t\t\tR_INT: begin\n\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\t// Mcount has already been incremented in R_MIX\n\t\t\t\t\tmcount <= mcount + 6'd1;\n\t\t\t\t\tif (mcount==2 || mcount==10)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount == 8)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 0;\n\t\t\t\t\t\tX0 <= X1;\n\t\t\t\t\t\tX1 <= Xmix;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount == 16)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 0; // Required\n\t\t\t\t\t\tX0 <= X1 ^ X0Save;\t// Same result as step 0 in R_MIX\n\t\t\t\t\t\tX1 <= Xmix ^ X1Save;\n\t\t\t\t\t\tmcount <= 2;\t\t// Skip 0 since done above\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t`endif\n\t\t\tendcase\n\t\tend\n`ifdef SIM\n\t// Print the final Xmix for each cycle to compare with scrypt.c (debugging)\n\tif (mstate == R_MIX && mcount == 17)\n\t\t$display (\"cycle %d Xmix %08x\\n\", cycle, Xmix[511:480]);\n`endif\n\tend\t// always @(posedge hash_clk)\n\nendmodule"
  },
  {
    "path": "experimental/hashvariant-C.v",
    "content": "/* hashvariant-C.v needs salsa-B.v - pipelined 2x clock speed (interleaving hashes)\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n\nNB This is full scratchpad ONLY. TODO get HALFRAM working.\n\n008,620\tSMixInRdya = 1\n017,230\tSMixInRdyb = 1\n172,160\tA: writeaddr=3ff\n172,320\tA: writeaddr=000\n180,780\tB: writeaddr=3ff\n180,940\tB: writeaddr=000\n356,800\tA: loadmixout, resultphase=0\n361,090\tA: finalhash = b303..4f7b OK, salsa A restart, PBKDF2_IN restart\n365,410\tB: loadmixout, resultphase=1, (SMixOutRdyb held until final_hash at 375,980)\n379,690\tA: SMixInRdya = 1 PBKDF2_IN done, salsa B restart\n375,980\tB: finalhash = 0da0..5c62 OK\n\n\n*/\n\n// DO NOT SET THIS ... TODO get it working\n//`define HALFRAM\n\t\n`timescale 1ns/1ps\n\nmodule hashcore (hash_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce);\n\n\tinput hash_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\t\t// Supports multicore (set MULTICORE below)\n\toutput [31:0] nonce_out;\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\t\n\treg poweron_reset = 1'b1;\n\treg reset = 1'b1;\n\treg phase = 1'd0;\n\treg resultphase = 1'd0;\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tpoweron_reset <= 1'b0;\n\t\treset <= poweron_reset;\t\t\t// Ensures a full clock cycle for reset\n\tend\n\n\twire [31:0] nonceinitval = data3[127:96];\n\treg [31:0] nonce_prevous_load = 32'hffffffff;\n\t\n\treg [27:0] nonce_cnt = 28'd0;\n\twire [31:0] nonce;\n\n\tassign nonce = { nonce_msb, nonce_cnt };\n\tassign nonce_out = nonce;\n\n\twire [31:0] nonce_2, nonce_2a, nonce_2b;\n\tassign nonce_2 = resultphase ? nonce_2b : nonce_2a;\n\t\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\t\n\treg golden_nonce_match = 1'b0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [31:0] blockcnt = 32'd0;\t// Takes values 1..4 for block iteration (NB could hardwire top 29 bits)\n\treg [1023:0] Xbuf = 1024'd0;\n\treg [1023:0] MixOut;\t\t\t// Salsa mixer ouput\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\t\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(hash_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\n\t// These flags control the interaction of the SHA256 and SalsaMix FSM's. While OK in simulation\n\t// Altera Quartus II barfs on synthesis, hence the ugly hack.\n\n\t// NB This relies on the execution times of the various operations to keep things in sync, vis stream a starts first,\n\t// then stream b starts 860 clocks later. Since its fullscratchpad the execution time is constant and stream a salsa\n\t// completes first. The result PBKDF2_SHA256_80_32 for stream a is completed before stream b salsa completed, so a new\n\t// PBKDF2_SHA256_80_128 is running when stream b salsa completes, which then needs to wait before its own PBKDF2_SHA256_80_32\n\t// can start. It should keep in sync even though it looks bonkers (we have a skycrane!)\n\t\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy, SMixInRdya, SMixInRdyb;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\treg Clr_SMixOutRdy = 1'b0;\n\twire Clr_SMixInRdya, Clr_SMixInRdyb;\n\twire Set_SMixOutRdya, Set_SMixOutRdyb;\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdya | Clr_SMixInRdyb)\n\t\tbegin\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\t\tnonce_cnt <= nonce_cnt + 28'd1;\n\t\tend\n\t\tif (Set_SMixOutRdya | Set_SMixOutRdyb)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdya)\n\t\t\tresultphase <= 1'b0;\n\t\tif (Set_SMixOutRdyb)\n\t\t\tresultphase <= 1'b1;\n\t\tif (loadnonce || (nonce_prevous_load != nonceinitval))\n\t\tbegin\n\t\t\tnonce_cnt <= nonceinitval[27:0];\t// The 4 msb of nonce are hardwired in MULTICORE mode\n\t\t\tnonce_prevous_load <= nonceinitval;\n\t\tend\n\tend\n\t\n\tassign SMixInRdy = (Clr_SMixInRdya | Clr_SMixInRdyb) ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixInRdya = ~phase & SMixInRdy;\n\tassign SMixInRdyb = phase & SMixInRdy;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : (Set_SMixOutRdya | Set_SMixOutRdyb) ? 1'b1 : SMixOutRdy_state;\n\t\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz). I don't even pretend to\n\t// understand how it works so please excuse any naive implimentation errors.\n\t\n\t// NB apparently this is poor coding style (sorry, I'm just a newbie here), but its working so\n\t// I'm not going to change it now (perhaps in a future version). It could also do with optimisation\n\t// though its not essential as the SHA256 does not limit the overall throughput.\n\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_XX=22,\t\t\t\t\t\t\t\t\t\t\t\t// Possibly superfluous (go straight to S_IDLE)\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\t\t\n\t\tif (reset == 1'b1)\n\t\t\tstate <= S_IDLE;\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tif (SMixOutRdy ||\t// Process output\n\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\tbegin\n\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\tblockcnt <= 32'd1;\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_2 : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tblockcnt, nonce, data3[95:0] };\n\t\t\t\t\t\tblockcnt <= blockcnt + 1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\n\t\t\t\tS_B6: begin\t// Shift output into X buffer from MSB->LSB\n\t\t\t\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\t\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\t\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\t\t\t\tXbuf[1023:768] <= tx_hash;\n\t\t\t\t\t\t// NB nonce is incremented in SMIX FSM\n\n\t\t\t\t\t\tif (blockcnt == 5)\n\t\t\t\t\t\t\tstate <= S_XX;\t// Done\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\tblockcnt, nonce, data3[95:0] };\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_XX: begin\n\t\t\t\t\t\t// State is possibly superfluous (go straight to S_IDLE from S_B6)\n\t\t\t\t\t\t// SMixInRdy <= 1;\t\t// Original\n\t\t\t\t\t\tSet_SMixInRdy <= 1;\t// Ugly hack\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\tend\n\t\t\t\t\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_2;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n\tend\n\n\t// Convert Xbuf to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = Xbuf[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\n\t\t// Also MixOut\n\t\twire [31:0] mix;\n\t\tassign mix = MixOut[`IDX(i)];\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\n\n\twire mixfeedback, mixfeedbacka, mixfeedbackb;\n\tassign mixfeedback = phase ? mixfeedbackb : mixfeedbacka;\n\n\twire addrsourceMix, addrsourceMixa, addrsourceMixb;\n\tassign addrsourceMix = phase ? addrsourceMixb : addrsourceMixa;\n\n\t`ifdef HALFRAM\n\t\treg [511:0] X0Save;\t\t// Save old value during interpolation\n\t\treg [511:0] X1Save;\n\t\treg\toddAddr = 1'b0;\t\t// Flag for odd addresses to interpolate\n\t`endif\n\twire [511:0] Xmix;\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of HALFRAM mode\n\twire [9:0] writeaddr, writeaddra, writeaddrb;\n\tassign writeaddr = phase ? writeaddrb : writeaddra;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\t`ifdef HALFRAM\n\t\tparameter ADDRBITS = 10;\n\t`else\n\t\tparameter ADDRBITS = 11;\n\t`endif\n\n\twire [ADDRBITS-1:0]ram_addr;\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\twire ram_wren, ram_wrena, ram_wrenb;\n\tassign ram_wren = phase ? ram_wrenb : ram_wrena;\n\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\treg [9:0] Xmixd = 10'b0;\n\talways @ (posedge hash_clk)\n\t\tXmixd <= Xmix[9:0];\t\t// Extra delay for hashvariant-B mix\n\t\n\t`ifdef HALFRAM\n\t\t// This is the half scratchpad version\n\t\tassign ram_addr = { phase, addrsourceMix ? Xmixd[9:1] : writeaddr[9:1] };\t// LSB is ignored\n\t`else\n\t\t// This is the full scratchpad version\n\t\tassign ram_addr = { phase, addrsourceMix ? Xmixd[9:0] : writeaddr };\t\t// MSB bit is phase\n\t`endif\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (ram_addr, ram_clk, ram1_din, ram_wren, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (ram_addr, ram_clk, ram2_din, ram_wren, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (ram_addr, ram_clk, ram3_din, ram_wren, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (ram_addr, ram_clk, ram4_din, ram_wren, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\n\treg [511:0] X0a, X0b;\n\treg [511:0] X1a, X1b;\n\t\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = phase ? {X1b, X0b} : {X1a, X0a} ;\t// Registered input\n\n\t// Salsa unit\n\n\tsalsa salsa_blk (hash_clk, mixfeedback, phase ? X0b : X0a, phase ? X1b : X1a, Xmix);\n\n\tparameter XSnull = 0, XSload = 1, XSmix = 2, XSram = 3;\n\n\twire [1:0] XCtla, XCtlb;\n\twire [511:0] X0ina, X0inb;\n\twire [511:0] X1ina, X1inb;\n\twire loadMixOuta, loadMixOutb;\n\n\tassign X0ina = (XCtla==XSmix) ? X1a : (XCtla==XSram) ? X0a ^ ramout[511:0] : (XCtla==XSload) ? X[511:0] : X0a;\n\tassign X1ina = (XCtla==XSmix) ? Xmix : (XCtla==XSram) ? X1a ^ ramout[1023:512] : (XCtla==XSload) ? X[1023:512] : X1a;\n\n\tassign X0inb = (XCtlb==XSmix) ? X1b : (XCtlb==XSram) ? X0b ^ ramout[511:0] : (XCtlb==XSload) ? X[511:0] : X0b;\n\tassign X1inb = (XCtlb==XSmix) ? Xmix : (XCtlb==XSram) ? X1b ^ ramout[1023:512] : (XCtlb==XSload) ? X[1023:512] : X1b;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tphase <= ~phase;\n\t\tX0a <= X0ina;\n\t\tX1a <= X1ina;\n\t\tX0b <= X0inb;\n\t\tX1b <= X1inb;\n\t\tif (loadMixOuta)\n\t\t\tMixOut <= { X1a, X0a };\n\t\tif (loadMixOutb)\n\t\t\tMixOut <= { X1b, X0b };\n\tend\n\t\n\tsalsa_fsm SFSMa (hash_clk, reset, SMixInRdya, nonce, XCtla, mixfeedbacka, addrsourceMixa, loadMixOuta, nonce_2a, ram_wrena, writeaddra, Set_SMixOutRdya, Clr_SMixInRdya );\n\n\tsalsa_fsm SFSMb (hash_clk, reset, SMixInRdyb, nonce, XCtlb, mixfeedbackb, addrsourceMixb, loadMixOutb, nonce_2b, ram_wrenb, writeaddrb, Set_SMixOutRdyb, Clr_SMixInRdyb );\n\t\nendmodule\t// End hashcore\n\nmodule salsa_fsm (hash_clk, reset, SMixInRdy, nonce, XCtl, mixfeedback, addrsourceMix, loadMixOut, nonce_2, ram_wren, writeaddr, Set_SMixOutRdy, Clr_SMixInRdy );\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\tparameter XSnull = 0, XSload = 1, XSmix = 2, XSram = 3;\n\n\tinput hash_clk;\n\tinput reset;\n\tinput SMixInRdy;\n\tinput [31:0] nonce;\n\n\toutput reg Set_SMixOutRdy = 1'b0;\n\toutput reg Clr_SMixInRdy = 1'b0;\n\n\tparameter R_IDLE=0, R_INIT=1, R_WRITE=2, R_MIX=3, R_INT=4;\n\treg [2:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg [6:0] mcount = 6'd0;\t\t// Salsa latency\n\treg doneROM = 1'd0;\t\t\t\t// Yes ROM, as its referred thus in the salsa docs. Maybe rename doneWRITE?\n\toutput reg mixfeedback = 1'b0;\n\toutput reg addrsourceMix = 1'b0;\n\toutput reg [1:0] XCtl = XSnull;\n\toutput reg loadMixOut = 1'b0;\n\toutput reg ram_wren = 1'b0;\n\n\treg [31:0] nonce_1 = 32'd0;\n\toutput reg [31:0] nonce_2 = 32'd0;\n\toutput reg [9:0] writeaddr = 10'd0;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tSet_SMixOutRdy <= 1'b0;\n\t\tClr_SMixInRdy <= 1'b0;\n\t\tXCtl <= XSnull;\n\t\tloadMixOut <= 1'b0;\n\t\tram_wren <= 1'b0;\n\t\tif (reset)\n\t\t\tmstate <= R_IDLE;\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\twriteaddr <= 0;\n\t\t\t\t\tmcount <= 0;\n\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\tif (SMixInRdy)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tXCtl <= XSload;\n\t\t\t\t\t\tmstate <= R_INIT;\n\t\t\t\t\t\tClr_SMixInRdy <= 1;\n\t\t\t\t\t\t// Save and increment nonce (NB done here not in SHA256 FSM)\n\t\t\t\t\t\tnonce_1 <= nonce;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_INIT: begin\n\t\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\tend\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\tmcount <= mcount + 6'd1;\n\t\t\t\t\t// NB One extra cycle is performed after ROM is complete to update X0,X1 to inital state for R_MIX\n\t\t\t\t\tif (mcount==0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\t\tif (writeaddr==1023)\n\t\t\t\t\t\t\tdoneROM <= 1'b1;\t\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\t\twriteaddr <= writeaddr + 10'd1;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount==8)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount == 6 || mcount == 14)\n\t\t\t\t\t\tXCtl <= XSmix;\n\t\t\t\t\tif (mcount == 7 || mcount == 15)\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tif (mcount == 14 && doneROM)\n\t\t\t\t\t\taddrsourceMix <= 1'b1;\n\t\t\t\t\tif (mcount == 15)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tif (doneROM)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tcycle <= 0;\n\t\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tram_wren <= 1'b1;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_MIX: begin\n\t\t\t\t\tmcount <= mcount + 6'd1;\n\t\t\t\t\tif (mcount == 0)\n\t\t\t\t\t\tXCtl <= XSram;\n\t\t\t\t\tif (mcount == 1)\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tif (mcount==2 || mcount==10)\n\t\t\t\t\t\tmixfeedback <= 1;\n\t\t\t\t\tif (mcount == 8 || mcount == 16)\n\t\t\t\t\t\tXCtl <= XSmix;\n\t\t\t\t\tif (mcount == 9 || mcount == 17)\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tif (mcount == 17)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tcycle <= cycle + 11'd1;\n\t\t\t\t\t\tif (cycle == 1023)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// Pipeline the result so we can start processing the next X input\n\t\t\t\t\t\t\tloadMixOut <= 1'b1;\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\tSet_SMixOutRdy <= 1'b1;\n\t\t\t\t\t\t\tnonce_2 <= nonce_1;\n\t\t\t\t\t\t\tmstate <= R_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tendcase\n\t\tend\n\tend\t// always @(posedge hash_clk)\n\nendmodule"
  },
  {
    "path": "experimental/salsa-B.v",
    "content": "/* salsa-B.v for use with hashvariant-B.v\n   Based on salsa3.v ... registered at the column-row interface (and final row output)\n\nLatency 2 clock cycle hence 4 salsa iterations in 8 cycles.\nNB Columns feed forward two levels into rows, so this is likely to be NON-OPTIMAL.\n\nHMMM, not sure if I can sensibly implement this, but I'll give it a go [MAYBE errors, possibly\nexplaining higher clock speed!]\n\nTHE FOLLOWING is for the OBSOLETE salsa-B1.v\nTODO redo it in ../SALSA for this version\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\nClocks 59/25 = 2.4 times faster, so the 4 cycle latency gives a slightly highe throughput overall!!\nBut wwhat about overclocking? TODO try for real.\n\nAHA ... its because I've registered the salsa_core output, which is NOT what I actually want\nas it breaks the FSM timing. Rename this salsa-B1.v and adjust the registers in salsa-B.v\n\n200MHz clock gives (ltcminer.sta.rpt) ... HMM should have used 60MHz, but good result anyway\n+------------------------------------------------------------------------------------------+\n; Slow 1200mV 85C Model Fmax Summary                                                       ;\n+-----------+-----------------+-----------------------------------------------------+------+\n; Fmax      ; Restricted Fmax ; Clock Name                                          ; Note ;\n+-----------+-----------------+-----------------------------------------------------+------+\n; 59.08 MHz ; 59.08 MHz       ; pll_blk|altpll_component|auto_generated|pll1|clk[0] ;      ;\n+-----------+-----------------+-----------------------------------------------------+------+\n-----------+-----------------------------------------------------+--------------+------------+------------+\n; Slack   ; From Node                                  ; To Node                                    ; Launch Clock                                        ; Latch Clock                                         ; Relationship ; Clock Skew ; Data Delay ;\n+---------+--------------------------------------------+--------------------------------------------+-----------------------------------------------------+-----------------------------------------------------+--------------+------------+------------+\n; -11.925 ; mixfeedback                                ; salsa:salsa_blk|salsa_core:salsa1|c10d[15] ; pll_blk|altpll_component|auto_generated|pll1|clk[0] ; pll_blk|altpll_component|auto_generated|pll1|clk[0] ; 5.000        ; 0.272      ; 17.192     ;\n\n\n\n* Copyright (c) 2013 kramble\n* Derived from scrypt.c Copyright 2009 Colin Percival, 2011 ArtForz\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\nmodule salsa (clk, feedback, B, Bx, Bo);\n\ninput clk;\ninput feedback;\ninput [511:0]B;\ninput [511:0]Bx;\noutput [511:0]Bo;\n\nwire [511:0]xx;\t\t\t// Initial xor\n\nwire [511:0]xr;\nreg [511:0]xrd;\n//salsa_core salsa1 (clk, feedback ? xr : xx, xr);\t// unregistered xr\nsalsa_core salsa1 (clk, feedback ? xrd : xx, xr);\t// registered xrd\n\nreg [511:0]xxd;\n\nalways @ (posedge clk)\nbegin\n\txxd <= xx;\n\txrd <= xr;\nend\n\ngenvar i;\ngenerate\n\tfor (i = 0; i < 16; i = i + 1) begin : XX\n\t\t// Initial XOR. NB this adds to propagation delay of the first salsa, may want register it.\n\t\tassign xx[`IDX(i)] = B[`IDX(i)] ^ Bx[`IDX(i)];\n\n\t\t// assign Bo[`IDX(i)] = xx[`IDX(i)] + xr[`IDX(i)];\t// Original\n\t\tassign Bo[`IDX(i)] = xxd[`IDX(i)] + xr[`IDX(i)];\t// Salsa-B\n\tend\nendgenerate\n\nendmodule\n\nmodule salsa_core (clk, xx, out);\n\ninput clk;\ninput [511:0]xx;\noutput [511:0]out;\t// NB out remains UNREGISTERED even though I have added c00d etc registers\n// output reg [511:0]out;\n\n// Some debugging assignments so we can check the word format\n/*\nwire [31:0]x00;\nwire [31:0]x04;\nwire [31:0]x12;\nassign x00 = xx[`IDX(0)];\nassign x04 = xx[`IDX(4)];\nassign x12 = xx[`IDX(12)];\n*/\n\n// This is clunky due to my lack of verilog skills but it works so elegance can come later\n\nwire [31:0]c00;\t\t\t// Column results\nwire [31:0]c01;\nwire [31:0]c02;\nwire [31:0]c03;\nwire [31:0]c04;\nwire [31:0]c05;\nwire [31:0]c06;\nwire [31:0]c07;\nwire [31:0]c08;\nwire [31:0]c09;\nwire [31:0]c10;\nwire [31:0]c11;\nwire [31:0]c12;\nwire [31:0]c13;\nwire [31:0]c14;\nwire [31:0]c15;\n\nwire [31:0]r00;\t\t\t// Row results\nwire [31:0]r01;\nwire [31:0]r02;\nwire [31:0]r03;\nwire [31:0]r04;\nwire [31:0]r05;\nwire [31:0]r06;\nwire [31:0]r07;\nwire [31:0]r08;\nwire [31:0]r09;\nwire [31:0]r10;\nwire [31:0]r11;\nwire [31:0]r12;\nwire [31:0]r13;\nwire [31:0]r14;\nwire [31:0]r15;\n\nwire [31:0]c00s;\t\t\t// Column sums\nwire [31:0]c01s;\nwire [31:0]c02s;\nwire [31:0]c03s;\nwire [31:0]c04s;\nwire [31:0]c05s;\nwire [31:0]c06s;\nwire [31:0]c07s;\nwire [31:0]c08s;\nwire [31:0]c09s;\nwire [31:0]c10s;\nwire [31:0]c11s;\nwire [31:0]c12s;\nwire [31:0]c13s;\nwire [31:0]c14s;\nwire [31:0]c15s;\n\nwire [31:0]r00s;\t\t\t// Row sums\nwire [31:0]r01s;\nwire [31:0]r02s;\nwire [31:0]r03s;\nwire [31:0]r04s;\nwire [31:0]r05s;\nwire [31:0]r06s;\nwire [31:0]r07s;\nwire [31:0]r08s;\nwire [31:0]r09s;\nwire [31:0]r10s;\nwire [31:0]r11s;\nwire [31:0]r12s;\nwire [31:0]r13s;\nwire [31:0]r14s;\nwire [31:0]r15s;\n\nreg [31:0]c00d;\t\t\t// Column results registered\nreg [31:0]c01d;\nreg [31:0]c02d;\nreg [31:0]c03d;\nreg [31:0]c04d;\nreg [31:0]c05d;\nreg [31:0]c06d;\nreg [31:0]c07d;\nreg [31:0]c08d;\nreg [31:0]c09d;\nreg [31:0]c10d;\nreg [31:0]c11d;\nreg [31:0]c12d;\nreg [31:0]c13d;\nreg [31:0]c14d;\nreg [31:0]c15d;\n\n/* From scrypt.c\n\n#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))\n\tfor (i = 0; i < 8; i += 2) {\n\t\t// Operate on columns\n\t\tx04 ^= R(x00+x12, 7);\tx09 ^= R(x05+x01, 7);\tx14 ^= R(x10+x06, 7);\tx03 ^= R(x15+x11, 7);\n\t\tx08 ^= R(x04+x00, 9);\tx13 ^= R(x09+x05, 9);\tx02 ^= R(x14+x10, 9);\tx07 ^= R(x03+x15, 9);\n\t\tx12 ^= R(x08+x04,13);\tx01 ^= R(x13+x09,13);\tx06 ^= R(x02+x14,13);\tx11 ^= R(x07+x03,13);\n\t\tx00 ^= R(x12+x08,18);\tx05 ^= R(x01+x13,18);\tx10 ^= R(x06+x02,18);\tx15 ^= R(x11+x07,18);\n\n\t\t// Operate on rows\n\t\tx01 ^= R(x00+x03, 7);\tx06 ^= R(x05+x04, 7);\tx11 ^= R(x10+x09, 7);\tx12 ^= R(x15+x14, 7);\n\t\tx02 ^= R(x01+x00, 9);\tx07 ^= R(x06+x05, 9);\tx08 ^= R(x11+x10, 9);\tx13 ^= R(x12+x15, 9);\n\t\tx03 ^= R(x02+x01,13);\tx04 ^= R(x07+x06,13);\tx09 ^= R(x08+x11,13);\tx14 ^= R(x13+x12,13);\n\t\tx00 ^= R(x03+x02,18);\tx05 ^= R(x04+x07,18);\tx10 ^= R(x09+x08,18);\tx15 ^= R(x14+x13,18);\n\t}\n*/\n\n// cols\n\nassign c04s = xx[`IDX(0)] + xx[`IDX(12)];\nassign c04 = xx[`IDX(4)] ^ { c04s[24:0], c04s[31:25] };\nassign c09s = xx[`IDX(5)] + xx[`IDX(1)];\nassign c09 = xx[`IDX(9)] ^ { c09s[24:0], c09s[31:25] };\nassign c14s = xx[`IDX(10)] + xx[`IDX(6)];\nassign c14 = xx[`IDX(14)] ^ { c14s[24:0], c14s[31:25] };\nassign c03s = xx[`IDX(15)] + xx[`IDX(11)];\nassign c03 = xx[`IDX(03)] ^ { c03s[24:0], c03s[31:25] };\n\nassign c08s = c04 + xx[`IDX(0)];\nassign c08 = xx[`IDX(8)] ^ { c08s[22:0], c08s[31:23] };\nassign c13s = c09 + xx[`IDX(5)];\nassign c13 = xx[`IDX(13)] ^ { c13s[22:0], c13s[31:23] };\nassign c02s = c14 + xx[`IDX(10)];\nassign c02 = xx[`IDX(2)] ^ { c02s[22:0], c02s[31:23] };\nassign c07s = c03 + xx[`IDX(15)];\nassign c07 = xx[`IDX(7)] ^ { c07s[22:0], c07s[31:23] };\n\nassign c12s = c08 + c04;\nassign c12 = xx[`IDX(12)] ^ { c12s[18:0], c12s[31:19] };\nassign c01s = c13 + c09;\nassign c01 = xx[`IDX(1)] ^ { c01s[18:0], c01s[31:19] };\nassign c06s = c02 + c14;\nassign c06 = xx[`IDX(6)] ^ { c06s[18:0], c06s[31:19] };\nassign c11s = c07 + c03;\nassign c11 = xx[`IDX(11)] ^ { c11s[18:0], c11s[31:19] };\n\nassign c00s = c12 + c08;\nassign c00 = xx[`IDX(0)] ^ { c00s[13:0], c00s[31:14] };\nassign c05s = c01 + c13;\nassign c05 = xx[`IDX(5)] ^ { c05s[13:0], c05s[31:14] };\nassign c10s = c06 + c02;\nassign c10 = xx[`IDX(10)] ^ { c10s[13:0], c10s[31:14] };\nassign c15s = c11 + c07;\nassign c15 = xx[`IDX(15)] ^ { c15s[13:0], c15s[31:14] };\n\n// rows\n\nassign r01s = c00d + c03d;\nassign r01 = c01d ^ { r01s[24:0], r01s[31:25] };\nassign r06s = c05d + c04d;\nassign r06 = c06d ^ { r06s[24:0], r06s[31:25] };\nassign r11s = c10d + c09d;\nassign r11 = c11d ^ { r11s[24:0], r11s[31:25] };\nassign r12s = c15d + c14d;\nassign r12 = c12d ^ { r12s[24:0], r12s[31:25] };\n\nassign r02s = r01 + c00d;\nassign r02 = c02d ^ { r02s[22:0], r02s[31:23] };\nassign r07s = r06 + c05d;\nassign r07 = c07d ^ { r07s[22:0], r07s[31:23] };\nassign r08s = r11 + c10d;\nassign r08 = c08d ^ { r08s[22:0], r08s[31:23] };\nassign r13s = r12 + c15d;\nassign r13 = c13d ^ { r13s[22:0], r13s[31:23] };\n\nassign r03s = r02 + r01;\nassign r03 = c03d ^ { r03s[18:0], r03s[31:19] };\nassign r04s = r07 + r06;\nassign r04 = c04d ^ { r04s[18:0], r04s[31:19] };\nassign r09s = r08 + r11;\nassign r09 = c09d ^ { r09s[18:0], r09s[31:19] };\nassign r14s = r13 + r12;\nassign r14 = c14d ^ { r14s[18:0], r14s[31:19] };\n\nassign r00s = r03 + r02;\nassign r00 = c00d ^ { r00s[13:0], r00s[31:14] };\nassign r05s = r04 + r07;\nassign r05 = c05d ^ { r05s[13:0], r05s[31:14] };\nassign r10s = r09 + r08;\nassign r10 = c10d ^ { r10s[13:0], r10s[31:14] };\nassign r15s = r14 + r13;\nassign r15 = c15d ^ { r15s[13:0], r15s[31:14] };\n\nwire [511:0]xo;\t\t\t// Rename row results\nassign xo = { r15, r14, r13, r12, r11, r10, r09, r08, r07, r06, r05, r04, r03, r02, r01, r00 };\n\nalways @ (posedge clk)\nbegin\n\tc00d <= c00;\n\tc01d <= c01;\n\tc02d <= c02;\n\tc03d <= c03;\n\tc04d <= c04;\n\tc05d <= c05;\n\tc06d <= c06;\n\tc07d <= c07;\n\tc08d <= c08;\n\tc09d <= c09;\n\tc10d <= c10;\n\tc11d <= c11;\n\tc12d <= c12;\n\tc13d <= c13;\n\tc14d <= c14;\n\tc15d <= c15;\n\t// out <= xo;\t// registered version\nend\n\nassign out = xo;\t// unregistered version\nendmodule\n"
  },
  {
    "path": "scripts/config.example.tcl",
    "content": "# Edit this with your details and save as config.tcl\n# They are the same worker server, user/pass you use\n# with other mining software.\n#\nset url \"http://mining-foreman.org:10341\"\nset userpass \"Username:Password\"\n\n"
  },
  {
    "path": "scripts/json_rpc.tcl",
    "content": "# Handles all the JSON-RPC stuff\npackage require http\npackage require json\npackage require base64\n\nproc do_rpc_request {url userpass request} {\n\tset headers [list \"Authorization\" \"Basic $userpass\"]\n\n\tset token [::http::geturl $url -query $request -headers $headers -type \"application/json\" -timeout 5000]\n\n\tset data [::http::data $token]\n\t::http::cleanup $token\n\n\treturn [json::json2dict $data]\n}\n\nproc get_work {url userpass} {\n\tarray unset work\n\n\tif [catch {\n\t\tset json_dict [do_rpc_request $url $userpass \"{\\\"method\\\": \\\"getwork\\\", \\\"params\\\": \\[\\], \\\"id\\\":0}\"]\n\t\tset json_result [dict get $json_dict result]\n\n\t\t# Midstate is not needed and breaks stratum proxy started -nm ...\n\t\t# set work(midstate) [dict get $json_result midstate]\n\t\tset work(data) [dict get $json_result data]\n\t\tset work(target) [dict get $json_result target]\n\t} exc] {\n\t\tsay_error \"ERROR: Unable to getwork. Reason: $exc\"\n\t\treturn -1\n\t}\n\t\n\treturn [array get work]\n}\n\nproc submit_work {url userpass workl} {\n\tarray set work $workl\n\n\tset nonce $work(nonce)\n\tset data $work(data)\n\n\t#set nonce [expr {$nonce - 132}] # No longer need to re-adjust nonce, the FPGA takes care of that.\n\tset nonce [format %08x $nonce]\n\n\tset hexdata1 [string range $data 0 151]\n\tset hexdata2 [reverseHex $nonce]\n\tset hexdata3 [string range $data 160 255]\n\tset hexdata \"${hexdata1}${hexdata2}${hexdata3}\"\n\n\t#puts \"Original data: $data\"\n\t#puts \"Golden data: $hexdata\"\n\n\t#puts \"Submitting work ...\"\n\t\n\n\tset accepted false\n\n\tif [catch {\n\t\tset json_dict [do_rpc_request $url $userpass \"{\\\"method\\\": \\\"getwork\\\", \\\"params\\\": \\[ \\\"$hexdata\\\" \\], \\\"id\\\":1}\"]\n\t\tset json_result [dict get $json_dict result]\n\t\tset json_error [dict get $json_dict error]\n\t\n\t\tif {($json_result == true) && ($json_error == {null})} {\n\t\t\tset accepted true\n\t\t}\n\t} exc] {\n\t\tsay_error \"ERROR: Unable to submit share. Reason: $exc\"\n\t\tset accepted false\n\t}\n\n\tif {$accepted == true} {\n\t\tsay_line \"$nonce accepted\"\n\t} else {\n\t\tsay_line \"$nonce _rejected_\"\n\t}\n\n\treturn $accepted\n}\n\n"
  },
  {
    "path": "scripts/jtag_comm.tcl",
    "content": "# JTAG Communication Functions\n# Abstracts the JTAG interface away to a few interface functions\n\n# User API Functions\n# These should be generic and be the same no matter what the underlying FPGA is.\n# Use these to interact with the FPGA.\n# TODO: These are designed to assume a single FPGA. Re-design to handle multiple FPGAs, assigning\n# an arbitrary ID to each FPGA.\n\n\n# Initialize the FPGA\nproc fpga_init {} {\n\tglobal fpga_last_nonce\n\tglobal fpga_name\n\n\tset fpga [find_miner_fpga]\n\n\tif {$fpga == -1} {\n\t\treturn -1\n\t}\n\n\tset hardware_name [lindex $fpga 0]\n\tset device_name [lindex $fpga 1]\n\n\tstart_insystem_source_probe -hardware_name $hardware_name -device_name $device_name\n\n\tset fpga_last_nonce [read_instance GNON]\n\tset fpga_name \"$hardware_name $device_name\"\n\n\treturn 0\n}\n\n\n# Push new work to the FPGA\nproc push_work_to_fpga {workl} {\n\tglobal fpga_last_nonce\n\tglobal verbose\n\tglobal testmode\n\tglobal test_prevnonce\n\tglobal prevtarget\n\tglobal diff\n\t\n\tarray set work $workl\n\n\tset target [string range [reverseHex $work(target)] 0 7]\n\t\n\t# Adjust data3 when in test mode\n\tset revdata [reverseHex $work(data)]\n\tset data3 [string range $revdata 64 127]\n\t\n\tif { $testmode } {\n\t\tset data3_nonce [string range $data3 32 39]\n\t\t# Need to subtract a few from the nonce else it does not match. The offset needed is\n\t\t# is a little variable, but 6 seems OK. TODO investigate why this is happening.\n\t\t# Perhaps write_instance is not sending data in strict order (eg if DAT3 completes\n\t\t# before DAT1 or DAT2 then the nonce will be set before the rest of data is ready)\n\t\t# Indeed, if the CPU is heavily loaded then a much higher offset is needed.\n\t\tset data3_nonce [expr 0x$data3_nonce - 50]\n\t\tif { $data3_nonce < 0 } {\n\t\t\tset data3_nonce 0\n\t\t}\n\t\t# Kludge since FPGA relies on detecting a different nonce to load the test nonce\n\t\t# NB it can still glitch unless we load the bitstream afresh each time since the fpga\n\t\t# remembers the final getwork sent from the previous test run.\n\t\tif { $test_prevnonce == $data3_nonce } {\n\t\t\tset data3_nonce [expr $data3_nonce + 1]\n\t\t}\n\t\tset test_prevnonce $data3_nonce\n\t\tset newdata3 [string range $data3 0 31]\n\t\tappend newdata3 [format \"%08x\" $data3_nonce]\n\t\tappend newdata3 [string range $data3 40 63]\n\t\tset data3 $newdata3\n\t}\n\t\n\t# work(data) is 128 bytes (ie the 80 byte header, padded to 128 bytes as per sha256)\n\t# we reverse the string first, so need to count backwards when indexing\n\twrite_instance \"DAT1\" [string range $revdata 192 255]\n\twrite_instance \"DAT2\" [string range $revdata 128 191]\n\twrite_instance \"DAT3\" $data3\n\n\t# Only write target the first time (and if it subsequently changes)\n\tif { $prevtarget != $target } {\n\t\twrite_instance \"TARG\" $target\n\t\tset diff [expr 0x0000ffff / 0x$target ]\n\t\tputs \"new target $target diff $diff\"\n\t}\n\t\n\tif { $verbose } {\n\t# Write it out for DEBUG\n\tputs [string range $revdata 192 255]\n\tputs [string range $revdata 128 191]\n\tputs $data3\n\tif { $prevtarget != $target } {\n\t\tputs \"target $target\"\n\t}\n\t}\n\t\n\tset prevtarget $target\n\t# Reset the last seen nonce, since we've just given the FPGA new work\n\tset fpga_last_nonce [read_instance GNON]\n}\n\n\n# Clear all work on the FPGA\nproc clear_fpga_work {} {\n\t# Currently does nothing, since these is no work queue\n}\n\n\n# Get a new result from the FPGA if one is available. Returns Golden Nonce (integer).\n# If no results are available, returns -1\nproc get_result_from_fpga {} {\n\tglobal fpga_last_nonce\n\tset golden_nonce [read_instance GNON]\n\n\tif { [string compare $golden_nonce $fpga_last_nonce] != 0} {\n\t\tset fpga_last_nonce $golden_nonce\n\t\t# Convert from Hex to integer\n\t\tset nonce [expr 0x$golden_nonce]\n\t\treturn $nonce\n\t}\n\n\treturn -1\n}\n\n\n# Return the current nonce the FPGA is on.\n# This can be sampled to calculate how fast the FPGA is running.\n# Returns -1 if that information is not available.\nproc get_current_fpga_nonce {} {\n\tif { [instance_exists NONC] } {\n\t\tset nonce [read_instance NONC]\n\t\treturn [expr 0x$nonce]\n\t} else {\n\t\treturn -1\n\t}\n}\n\n\n# Return the FPGA's \"name\", which could be anything but is hopefully helpful (to the user) in\n# indentifying which FPGA the software is talking to.\nproc get_fpga_name {} {\n\tglobal fpga_name\n\treturn $fpga_name\n}\n\n\n\n###\n# Internal FPGA/JTAG APIs are below\n# These should not be accessed outside of this script\n###################################\n\nset fpga_instances [dict create]\nset fpga_last_nonce 0\nset fpga_name \"Unknown\"\n\n# Search the specified FPGA device for all Sources and Probes\nproc find_instances {hardware_name device_name} {\n\tglobal fpga_instances\n\n\tset fpga_instances [dict create]\n\n\tif {[catch {\n\n\t\tforeach instance [get_insystem_source_probe_instance_info -hardware_name $hardware_name -device_name $device_name] {\n\t\t\tdict set fpga_instances [lindex $instance 3] [lindex $instance 0]\n\t\t}\n\n\t} exc]} {\n\t\t#puts stderr \"DEV-REMOVE: Error in find_instances: $exc\"\n\t\tset fpga_instances [dict create]\n\t}\n}\n\nproc write_instance {name value} {\n\tglobal fpga_instances\n\twrite_source_data -instance_index [dict get $fpga_instances $name] -value_in_hex -value $value\n}\n\nproc read_instance {name} {\n\tglobal fpga_instances\n\treturn [read_probe_data -value_in_hex -instance_index [dict get $fpga_instances $name]]\n}\n\nproc instance_exists {name} {\n\tglobal fpga_instances\n\treturn [dict exists $fpga_instances $name]\n}\n\n\n# Try to find an FPGA on the JTAG chain that has mining firmware loaded into it.\n# TODO: Return multiple FPGAs if more than one are found (that have mining firmware).\nproc find_miner_fpga {} {\n\tset hardware_names [get_hardware_names]\n\n\tif {[llength $hardware_names] == 0} {\n\t\tputs stderr \"ERROR: There are no Altera devices currently connected.\"\n\t\tputs stderr \"Please connect an Altera FPGA and re-run this script.\\n\"\n\t\treturn -1\n\t}\n\n\tforeach hardware_name $hardware_names {\n\t\tif {[catch { set device_names [get_device_names -hardware_name $hardware_name] } exc]} {\n\t\t\t#puts stderr \"DEV-REMOVE: Error on get_device_names: $exc\"\n\t\t\tcontinue\n\t\t}\n\n\t\tforeach device_name $device_names {\n\t\t\tif { [check_if_fpga_is_miner $hardware_name $device_name] } {\n\t\t\t\treturn [list $hardware_name $device_name]\n\t\t\t}\n\t\t}\n\t}\n\n\tputs stderr \"ERROR: There are no Altera FPGAs with mining firmware loaded on them.\"\n\tputs stderr \"Please program your FPGA with mining firmware and re-run this script.\\n\"\n\n\treturn -1\n}\n\n\n# Check if the specified FPGA is loaded with miner firmware\nproc check_if_fpga_is_miner {hardware_name device_name} {\n\tfind_instances $hardware_name $device_name\n\n\tif {[instance_exists DAT1] && [instance_exists DAT2] && [instance_exists DAT3] && [instance_exists NONC] && [instance_exists GNON]} {\n\t\treturn 1\n\t}\n\n\treturn 0\n}\n\n\n\n"
  },
  {
    "path": "scripts/mine.bat",
    "content": "%QUARTUS_ROOTDIR%\\bin\\quartus_stp -t mine.tcl\nPAUSE"
  },
  {
    "path": "scripts/mine.sh",
    "content": "#!/bin/bash\n# QROOT is the root directory of your quartus install\n# Mine is ~/altera/13.1/quartus/ but yours may be different\nQROOT=~/altera/13.1/quartus  # change to your directory\n$QROOT/bin/quartus_stp -t mine.tcl\n"
  },
  {
    "path": "scripts/mine.tcl",
    "content": "##\n#\n# Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n#\n#\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n# \n##\n\n\n## TODO: Long polling.\n## TODO: --verbose option for debugging issues.\n## TODO: Handle multiple FPGAs at once.\n\n\npackage require http\npackage require json\npackage require base64\n\nsource utils.tcl\nsource json_rpc.tcl\nsource jtag_comm.tcl\n\n# Configuration\n# -------------\n# Additional DEBUG output getwork and current nonce ...\nset verbose 0\n# Reads getwork (including nonce) from a file ...\nset testmode 0\n# Delay between getwork requests (in seconds) ...\nset ask_rate 20\n\t\t\t\nset total_accepted 0\nset total_rejected 0\n\nset test_total 0\nset test_matches 0\nset test_errors 0\nset test_prevnonce 0\nset prevtarget \"none\"\n# Diff is just used for reporting, calculated from target so this is overwritten\nset diff 32\n\nproc say_line {msg} {\n\tset t [clock format [clock seconds] -format \"%D %T\"]\n\tputs \"\\[$t\\] $msg\"\n}\n\nproc say_error {msg} {\n\tset t [clock format [clock seconds] -format \"%D %T\"]\n\tputs stderr \"\\[$t\\] $msg\"\n}\n\nproc say_status {rate est_rate accepted rejected curnonce} {\n\tglobal verbose\n\tset submitted [expr {$rejected + $accepted}]\n\n\tif {$submitted == 0} {\n\t\tset rej_rate [expr {$rejected * 100.0}]\n\t} else {\n\t\tset rej_rate [expr {$rejected * 100.0 / $submitted}]\n\t}\n\n\t# BTC ...\n\t# say_line [format \"%.2f MH/s (~%.2f MH/s) \\[Rej: %i/%i (%.2f%%)\\]\" $rate $est_rate $rejected $submitted $rej_rate]\n\t\n\t# LTC ...\n\tif { $verbose } {\n\t\tsay_line [format \"%.2f kH/s (~%.2f kH/s) \\[Rej: %i/%i (%.2f%%)\\] n=%08x\" $rate $est_rate $rejected $submitted $rej_rate $curnonce]\n\t} else {\n\t\tsay_line [format \"%.2f kH/s (~%.2f kH/s) \\[Rej: %i/%i (%.2f%%)\\]\" $rate $est_rate $rejected $submitted $rej_rate]\n\t}\n}\n\n# Loop until a new share is found, or timeout seconds have passed.\n# Prints status updates every second.\nproc wait_for_golden_ticket {timeout} {\n\tglobal total_accepted\n\tglobal total_rejected\n\tglobal global_start_time\n\tglobal diff\n\t\n\t#puts \"Current nonce\"\n\t#set current_nonce [read_instance GNON]\n\t#puts $current_nonce\n\tset last_nonce [get_current_fpga_nonce]\n\tset begin_time [clock clicks -milliseconds]\n\n\t#puts \"FPGA is now searching for lottery ticket...\"\n\n\twhile {$timeout > 0} {\n\t\tset golden_nonce [get_result_from_fpga]\n\n\t\tif {$golden_nonce != -1} {\n\t\t\treturn $golden_nonce\n\t\t}\n\n\t\t# TODO: We may need to sleep for a small amount of time to avoid taxing the CPU\n\t\t# Or the JTAG comms might throttle back our CPU usage anyway.\n\t\t# If the FPGA had a proper results queue we could just sleep for a second, but\n\t\t# for now we might as well loop as fast as possible\n\t\t\n\t\tset now [clock clicks -milliseconds]\n\t\tif { [expr {$now - $begin_time}] >= 2000 } {\n\t\t\tincr timeout -2\n\n\t\t\tset current_nonce [get_current_fpga_nonce]\n\t\t\tset dt [expr {$now - $begin_time}]\n\t\t\tset begin_time $now\n\n\t\t\tif {$current_nonce < $last_nonce} {\n\t\t\t\tset nonces [expr {$current_nonce + (0xFFFFFFFF - $last_nonce) + 1}]\n\t\t\t} else {\n\t\t\t\tset nonces [expr {$current_nonce - $last_nonce + 1}]\n\t\t\t}\n\n\t\t\tset last_nonce $current_nonce\n\n\t\t\tif {$dt == 0} {\n\t\t\t\tset dt 1\n\t\t\t}\n\n\t\t\t# set rate [expr {$nonces / ($dt * 1000.0)}]\n\t\t\tset rate [expr {$nonces / ($dt * 1.0)}]\n\t\t\tset current_time [clock seconds]\n\t\t\t\n\t\t\t# Adding 0.00001 to the denom is a quick way to avoid divide by zero :P\n\t\t\t\n\t\t\t# BTC: each share is worth ~(2^32 / 1,000,000) MH/s\n\t\t\t# set est_rate [expr {($total_accepted + $total_rejected) * 4294.967296 / ($current_time - $global_start_time + 0.00001)}]\n\t\t\t\n\t\t\t# LTC: each share is worth ~(2^32 / 0x7ff / 1,000) kH/s ... sort of a guess really\n\t\t\t# Difficulty is calculated from target ...\n\t\t\tset est_rate [expr {($total_accepted + $total_rejected) * 65.59 * $diff / ($current_time - $global_start_time + 0.00001)}]\n\n\t\t\tsay_status $rate $est_rate $total_accepted $total_rejected $current_nonce\n\t\t}\n\t}\n\n\treturn -1\n}\n\nproc submit_nonce {workl golden_nonce} {\n\tglobal total_accepted\n\tglobal total_rejected\n\tglobal url\n\tglobal userpass\n\n\tarray set work $workl\n\n\tset share(data) $work(data)\n\tset share(nonce) $golden_nonce\n\n\tif {[submit_work $url $userpass [array get share]] == true} {\n\t\tincr total_accepted\n\t} else {\n\t\tincr total_rejected\n\t}\n}\n\nproc parse_work_from_file {line} {\n\tarray unset work\n\n\tset work(midstate) \"0000000000000000000000000000000000000000000000000000000000000000\"\n\tset work(data) $line\n\tset work(target) \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff070000\"\n\t\n\treturn [array get work]\n}\n\n\nputs \" --- FPGA Mining Tcl Script --- \\n\\n\"\n\nif { $testmode } {\n\tputs \"INFO Running in TEST mode, reading from test_data.txt\\n\"\n\t# Short test set\n\tset testfp [open \"test_data.txt\" r]\n\t# 1000 from ltc blockchain all valid\n\t#set testfp [open \"test_data_full.txt\" r]\n\t# Removed nonces > 0x0fffffff for multicore builds\n\t#set testfp [open \"test_data_cut.txt\" r]\n}\n\nputs \"Looking for and preparing FPGAs...\\n\"\nif {[fpga_init] == -1} {\n\tputs stderr \"No mining FPGAs found.\"\n\tputs \"\\n\\n --- Shutting Down --- \\n\\n\"\n\texit\n}\n\nset fpga_name [get_fpga_name]\nputs \"Mining FPGA Found: $fpga_name\\n\\n\"\n\nif {[get_current_fpga_nonce] == -1} {\n\tputs \"WARNING: The FPGA's mining firmware does not report a hashrate. Status messages will show 0.00 MH/s, but the FPGA should still be running. Check the estimated rate for approximate hashing rate after shares have been submitted.\\n\\n\"\n}\n\nsource config.tcl\nset userpass [::base64::encode $userpass]\nset global_start_time [clock seconds]\n\n\nset work -1\n\nwhile {1} {\n\t# Get new work\n\tif { $testmode } {\n\t\tif { [gets $testfp line]\t< 0 } {\n\t\t\tputs \"EOF on test data\"\n\t\t\tputs \"$test_matches OK, $test_errors errors out of $test_total tested\"\n\t\t\tbreak\n\t\t}\n\t\t# Status each time is useful for large test files\n\t\tputs \"$test_matches OK, $test_errors errors out of $test_total tested\"\n\t\tset newwork [parse_work_from_file $line]\n\t\tset test_total [expr $test_total + 1]\n\t} else {\n\t\tset newwork [get_work $url $userpass]\n\t}\n\n\tif {$newwork != -1} {\n\t\t# Check to see if the FPGA completed any results while we were getting new work.\n\t\tset golden_nonce [get_result_from_fpga]\n\n\t\tif {$golden_nonce != -1 && [array exists work]} {\n\t\t\tsubmit_nonce [array get work] $golden_nonce\n\t\t}\n\n\t\tpush_work_to_fpga $newwork\n\t\tunset work\n\t\tarray set work $newwork\n\t}\n\n\t# Even if we couldn't get new work above, we should still loop looking for results,\n\t# because the FPGA will (currently) continue to mine.\n\t# TODO: In the future the FPGA will go idle once it completes its work.\n\t\n\t# We wait 20 seconds, because after 20 seconds we should go get new work from the pool.\n\t# Getting new work every 20 seconds helps prevent stale shares.\n\t# TODO: Implement Long Polling ... :P\n\n\t# kramble: now using $ask_rate set at top of file\n\tset golden_nonce [wait_for_golden_ticket $ask_rate]\n\n\tif {$golden_nonce == -1 || ![array exists work]} {\n\t\tcontinue\n\t}\n\n\tif { $testmode } {\n\t\t# Check golden_nonce\n\t\tset gn [string range [reverseHex $work(data)] 96 103]\n\t\tif { [format \"%08x\" $golden_nonce] != $gn } {\n\t\t\tputs [format \"ERROR golden nonce %08x does not match expected $gn\" $golden_nonce]\n\t\t\tset test_errors [expr $test_errors + 1]\n\t\t} else {\n\t\t\tputs [format \"OK golden nonce correct %08x\" $golden_nonce]\n\t\t\tset test_matches [expr $test_matches + 1]\n\t\t}\n\t\t\n\t} else {\n\t\tsubmit_nonce [array get work] $golden_nonce\n\t}\n}\n\n\nputs \"\\n\\n --- Shutting Down --- \\n\\n\"\n\n\n\n"
  },
  {
    "path": "scripts/program-fpga-board.bat",
    "content": "@ECHO off\n\n%QUARTUS_ROOTDIR%\\bin\\quartus_stp.exe -t program-fpga-board.tcl\n\nREM PAUSE\n"
  },
  {
    "path": "scripts/program-fpga-board.tcl",
    "content": "##\n#\n# Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n#\n#\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n# \n##\n\n\n# Some helpful functions\nproc get_selected_list_item {lst idx} {\n\t# Convert to integer\n\tif [catch { set idx [expr {int($idx)}] }] {\n\t\tset idx -1\n\t}\n\n\tif {$idx < 0 || $idx >= [llength $lst]} {\n\t\tset len [llength $lst]\n\t\tputs \"Invalid number. Please enter a number from 0 to $len\"\n\t\texit\n\t}\n\n\treturn [lindex $lst $idx]\n}\n\n\n# Let the user select a hardware cable to talk to\nset hardware_names [get_hardware_names]\nset id 0\n\n# List out all hardware names and the devices connected to them\nforeach hardware_name $hardware_names {\n\tputs \"$id) $hardware_name\"\n\tincr id\n\n\tforeach device_name [get_device_names -hardware_name $hardware_name] {\n\t\tputs \"\\t$device_name\"\n\t}\n}\n\nif {[llength $hardware_names] == 0} {\n\tputs \"There are no Altera devices currently connected.\"\n\texit\n}\n\nputs -nonewline \"\\nWhich USB device would you like to program? \"\ngets stdin selected_hardware_id\nputs \"\"\n\nset hardware_name [get_selected_list_item $hardware_names $selected_hardware_id]\n\nputs \"Selected USB device: $hardware_name\\n\\n\\n\"\n\n\n# Now let the user select which SOF to program\nset sof_files [glob *.sof]\nset id 0\n\nforeach sof_file $sof_files {\n\tputs \"$id) $sof_file\"\n\tincr id\n}\n\nif {[llength $sof_files] == 0} {\n\tputs \"I could not find any SOF files in the local directory. Quitting...\"\n\texit\n}\n\nputs -nonewline \"\\nWhich SOF would you like to use? \"\ngets stdin selected_sof_id\nputs \"\"\n\nset sof_name [get_selected_list_item $sof_files $selected_sof_id]\n\nputs \"Selected SOF file: $sof_name\\n\\n\\n\"\n\n\n# Now program the bugger\nputs \"Programming ...\"\n#quartus_pgm -c $hardware_name -m JTAG -o P;$sof_name\nset operation \"P;$sof_name\"\nif {[catch {exec quartus_pgm -c $hardware_name -m JTAG -o $operation} result]} {\n\tputs \"\\nResult: $result\\n\"\n\tputs \"ERROR: Programming failed.\\n\"\n} else {\n\tputs \"Programming successful! :D\"\n}\n\n\n\n"
  },
  {
    "path": "scripts/test_data.txt",
    "content": "000000015c272edd8baf2e6488ee18083aee8d902c28a1567d63ffd0af75516769f87f4ff37c02631f85dd758d97dc4f7494468e11c3438ac4837aebb5b7bacb7343a6c351e909161b44717eb1010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013051ebb602455449d3d462644489d51c2c9b4a2a72d211be0e5655a886c69f2c7fae46b1b197f10f8a7367aa0acc3335327a9eec5c9952069ab0fd5404ee516951e90d0a1b44717ed3070000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014eb4577c82473a069ca0e95703254da62e94d1902ab6f0eae8b1e718565775af20c9ba6ced48fc9915ef01c54da2200090801b2d2afc406264d491c7dfc7b0b251e91f141b44717e8f310000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ca905cf39dfd30f5f24c7a4637bc228d0f630790a52e8fc1e4edd173c985b3645c8dc64bcbe2b47e5f6f63a532049ca31fee38dad838b4674b6f09e487eeff4b51e93d471b44717efd390000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000183ef2b9ea41268bc8cda280460a6118fc0129d6e41d27ee4249671d1f8f1692a8fd570972571f73f6b6398097948df21fd308be4e1dbdb015620346ab80d632051e942811b44717e69180000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016ae3ee76c82148acf9491fc7726ab07ce7e72a8d7c12fd9d5a2e6081afcdbe94f455d2ee4b1fc5133e938ad6517433d1636ad0e028a6f33806ab07e2a85e313951e95f701b44717e753b0000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014cd5270ddcd143405cfcce2d34bda327dc2e6b1fe1319e1cd4263d90930c6f1dd84e9b2a5964494f3917d39f151fee10b656ecdd90c361eab93ff6ec5dd871a151e966071b44717e110e0000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011c18f51de681c01c9c2e899aca2f76e72c42048f3e3cf94d0ad7a11ec379b77805fabf535ea60eb2040f15758235377bd3c0ea53bf1221ab80c6bc85fb50ec3551e968f51b44717e68000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001398cb06ac42e39f36ff2539fedb11e8d2c3a78c8c2c27c87276400de00fd220aae15be45da722e4c1f09e6d4a7819a38eabcf9fe914304212159047367d27be251f63dda1b47c7eaaa160000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a714038f6648d7c21951bca8331842a3457d10b5eb78595125577637500be4c5e23c091d5136442d65bcf18f7a44e00243a25c652afb5b85e730566b8a8808cd51f64e521b47c7ea58250000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n"
  },
  {
    "path": "scripts/test_data_cut.txt",
    "content": "00000002c800429c934697c3228799ee485d51423d3560d02fac1e321491bfe9502eaafa1748c8b5c2a4cf00e3241c72401faf1fed97c06c9f0a3f4e43cd87776d06af5351faec8e1b496c9afc200900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d571bd129475fc9c43195a86f726f595ecf856e53334eff54ce72f4d7f439bd07121364ae4144e2aa8507af42f14c60e3dab5bc9c1728e46c48a4d028e4271c251faed141b496c9a480c1f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ce1995f9b33027049eca6ef5a679d7c1a94196f61492a1405c54a4ad10cbc541ad463e5d87d301737a52439a2c1667ea91f3c1a8ce278d1f7f68d7bd13fab41851faed191b496c9aa4b30c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021358fb1f11c0ee897e023623db46731849b3fc842964da09f7979edc96a475c459edfa827ef8fdee44442dd5d5860b18066c6bcf306c663eaa3aa258b5ad925e51faee371b496c9ab0d36500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024302b4b37d6c76c409d2a0c1dc23223c10a7342ab1234e51bc761fcd83b86eb619048b17e1cc6f6f4a9174e3e841e04ace20ddbb12128f8e5082e760436debe251faee511b496c9a0edf2801000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020317a63f446c64b512f837ff5fb2ad008ef8f4b42d8b1ffdd493a0d57318bcb42f28497bdeb660c98b6addc3b7d8b157a5c95f99e0694eacc421f7c0206191f851faee7d1b496c9ab1e42c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000210ee5da9ef549dd28cde08983173217c3f3032d12eccd7c408c34b6743a2f1c1d0ec41ac6bef6d9a222cce76c3e3515b0bbdd1a0c58863763501afead93158a251faeedb1b496c9a7b31d401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ba685c46cd25d63af19f614364dc2ed9a43a3066ae909834313b0fc94d997d6635c69f674e89c567ce29e967bf9e9006ec1d2acbb3b1176307fe370599e4ca4851faef281b496c9a31d28e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c781c405ac64642eec3c4a8f893da9708bf49a590e59be2892da8aa2be5a912f9c16b568765a34e8f041434b264b3bc75b6501ff6d7f54bc101133f5fab59ab851faefba1b496c9a53225300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002548ddc4ba85d2df8e7518286cca4405467645a763f056f7eeff97656533d072fcf7561ddc703b69572dd685ec6b7f683a5ca3ec377e44b4bbf42d85237ccf84151faf0fd1b496c9a42d90300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c6db2fa5273a6900d8fbcf453744bb1b49414372cf4ace29f16d9304780b375d5a0b5575217037a800f84b34a273f47b8804d706c8c9270892ed1432880dc70651faf1031b496c9aa65ade00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021ab293794b87e8ceaa7c58122bf4fa08ea841cc15f577a6e226050833f0f274474d234bec1505f3517a686261d5600c2645d32bcc5315b0b0c58b0439596e7bf51faf1331b496c9aee93b500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e0df43e775db70ac7de93a56650ef06b0586855474585c8b7fca532539eb8db0c7dbd6cbd101347fa5ca564baf946b64b830b8a7a9ed2424f566c4f3c1c5e82851faf1491b496c9a72f59200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000255c80f7010299fd8b4e1efff9b07edb051f5964efb92adbbc9400c521142db7311125e9d6aa8581c02c173d30b7e62389bf605a015706dba66112a9502fc9b9251faf1941b496c9a64761300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b8bfc8f56b384f03e93a535674ae0612055f112b8a358f36bee7bcb1697b59dd3199071abbe7061151050682ae450cce2acd71b79a56cbe9313db59ff1b8736b51faf3dd1b496c9a62b11500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000299d3c3a5c64e752aa3271423c5e015b82bd02fbac08be84872fab70f3f5bce1a2e187e7518cbdc9edee9b953b6706f28c8e1c796754d20336b6b0738042c4add51faf3e81b496c9ade1df600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a9d24491d1a01fcafb680692b99f62dab53d073e1b6239b7990030a47388de838dbfe1d2cfbd0fdd931db8a000095beabc88dfbf7c5c09faa5a6a3850ef864f951faf5cc1b496c9a06582a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e661bf95fcb102d9c6e95d91c754d5e46f9a44d8247e0060e438cbbe170090076af68394c9a0ad510f030627460beff9bd1ed4f6630b9d518ef6358cb66308ed51faf9651b496c9a13e74f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023aa75b93be847fde5b4d3ebaaad2546dd7692b1815b25bee221609bf3d2f46575a7badf661e10dc072fc7d8219935ad8e6798587a90af005aaaab8a150d295d651fafa851b496c9a27f97700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025abb33d96ee5292edba2eee0e8346dea30217f0c7dc3c15f52b2f183704a6911981caf4756a8dccccae0fa8c5d1e7b38e89e745c5f1215edbed3076df87df07451fafab51b496c9a6e543c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020dee07019ebd47c35e96d37d69e27f3ef13d0f81756a41b91ac0442718ad25ee2e725dd33fba31ed73e135c3d3849f41e1a6dead480766bff06b6fabcd63e6d351fafb231b496c9a71821800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f6c8c9836f6dbeb1bc6c9c74e2224f8fb7932132704bdd69fc0cb9d31ea414747e9aee846f57e569c5dcc91c4fb10a93fdc3038c91a22e574f484ca38eae9d7c51fafb2b1b496c9a3f9f9200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001bec9bf3239ca0920d27842e8e96ac4bbcc5d9460f840cc6ed013e1611b4532d6afebb0cf574887674d11133aa656885f591d50c90b7655bcc066c9d7236fa42951fafb891b496c9a85e3bd00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fcce0384add10421890a35109335cc5171fd0b3abfe3d0fab158026870ffc462d9972d25517735317a7a3eb3cfaf7a0c7ed63c19453971dc57e3df6d106ae8aa51fafbba1b496c9ad2073900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002aa0e6ccfc7974fa8f1a8e655da9185c18cf628aa74d71f7cdf944e8fc450dc79bc69e21942a8c0af06ae44a2225ccb7f06956fc189de2d717ac3b514901adeb351fafdb11b496c9a8c93f900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021600319f1e06e02c284fdb6ef3e816b5400009011382d04851ce2897a4c00a2946a1fc16ec905837513a6360cff527ab43a9a021f8263fde7f570d9649294ab451fafe211b496c9ae3230200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000293fb31984f83fd65257c5a479dcb7f3d36082f07a6ae7df3340f59d10339698002615323f01d4ba4bb60b4e258d4e9ef1fa4bdfd50c43acc478614cfe31c499651fafe0c1b496c9aee23df00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000106c945404ce2dbc440fdc0d9633b423832cf1b441fd503173f2486d1a08b2491ad77e906b87cb36b7d94a74f5a223766039178e7db49682b544ee53ad688de0d51fb000f1b496c9a026a2800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ae0d4ebd899f12f446809804ae3dda9c8bfea5e6acf80a88456c8d16bb7f274c8749d98838cf725eca769ae68411a4533b37191a88b81dfab5f2c3c79a3ee2f851fb00591b496c9a3dc80200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000265635df3c870d290d409a0b2d6d2e58e2fc5985997f86cdeabbe944cfa29d73928417da2c98be85b4251a4e36bcc84018a58af41800d93ceec53aca6de92f9a551fb00f11b496c9a60b45b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001515dabb0e77056baec7278f97222ca50f1f571ea90b1892d3338b48d3917e5add4a2c290bbe5fcf81772878607b4adf52ebd998f43836bffce194d60aa2eeb8b51fb01471b496c9ae3012600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a0f030f6c93f6f216f439033ca1f6917fc2af73dd8a463f1cf7dfdb465fec2a8e60655b389d3b18c05984231e3100513667a7497b1c3429a3d5f0a17c23a2a3d51fb02561b496c9a1fa33100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000109a34a587396b60fba9a1179a9895c8f9c8c2e9a1e149b6c0f66bbe496ffeaf0abd0ad3b57595a7153fbbf74b68ff378b5393e4fc069613bd81330cbaddfda9051fb02981b496c9add95b700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f1a6059a66c81f54cc35f142179aa405e56b54ae1422a130d6514231aaa05ca37359b0cfd2c0666469c1a749475cfa669fadb3b6834017397117f89b8840168a51fb02b01b496c9ae8753601000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001619ad66ba3c1055fc0108df52953fe56e9223b7f1b260b59d2da9b3cc8fe4f72ec6f909e6ef7567062442629af618fb926a7393b549cce27ff73108dd2dd3f6d51fb02dd1b496c9a60781100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001dcd762cd5fdc3bc2a4e27fab305cacb1bec81fead10a938e984bee41700817ca4a3e8c4d0648dc8681d76349bbadf6b9bdf84c8de81c9f6488bb65566182ccee51fb03d41b496c9afd7c5400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d7be028ad201c136f0022de600e9eec8c82faddb315221c703cb1068bde957a206d5b44c101fd3c204768cf6aeecf85a14043f69bdf45893dde90ab1135e823451fb040d1b496c9a18130301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d1d62ba1eb5685a614a29167fb4ff2c478599f162d2b7c037f4253dbd6f58e2f617fac1f45e9b7270d9ee9682e28ef318e9494611205de7066415add4e3c138c51fb04671b496c9a33516b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000276df33aa821649abced424e3195610b4480964d0127564fe562b6b10233d62d149681133ebeb2da88460241c82b1eb1e108dbbb97a3e8c952ac0acfe9508930451fb04cc1b496c9afc3b3300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eb27047b60592c3fe46589945f40f631a8c48baa2cc264e0788bd877e54486ae8dba93dfcadcef42ccce66025533511ac30f8ff46a4cbcc47c4286a2f0b3fdfd51fb05b61b496c9a40109900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e5169049d4adde21df2f17da3bc4210338984f2321e94e3619f2becb3a51be7da4b3b8c48923dcd813c65bc4c2d4ef341492ada6c2033d0eec58cc2692bc874351fb061b1b496c9ae2152b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025ec972109038207f25a48f4bd2c510a1d946a5f959cf2561ab83c3978cca533de64439955c986232aed8f7bc6aa2dca654e8a6ca8ac0c11b99f307994789f41051fb06691b496c9add001400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014d322538ac127b5f41dae018d140a3b5a08fab0f3ad18f92e162e7f2c33b1eed8d58c5f8a2fdb4602ac3a04014a5845ae36863e5b0786ac1e1cea05a277f8afc51fb07021b496c9ada340700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e178c5f4ef9c395f4570329ee9803c8271da256abed7fc6afe579ab4017c8a97f57079cfa53c6a4b7e5e8cdcc252a8aba11ea09b80faa34a11cce8e9184200b851fb07911b496c9acaba0e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000126b07330c03327fe49725ab1bb2d4aa634bba5c105f31bcfe146d01fb9bf2d03a23cf30806db84ac90eaad8374b6088a9119e283613765e2e72b3ecce512510051fb07ce1b496c9a2d8e6e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026d8ab7f8bf3a4a1f13e66b838af7bf9a2a11891193234e8a7c1c8aac0472e0d89acc69461af0dd923cb8cfe656ad2762a6428ecdff8d664d9ebfe647c3ed244251fb09981b496c9af60ed700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a2bf2dcb20932f49989e3f9a79020673dab713d1e4d5dc8aaf46cb14d9e9a1197e15fe1614c2fde40009e928ac3840307e71e37b09b170cf90f3ccae815a81e751fb09d81b496c9a3403b700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002776deda2570e41ffbe48932fbd8f6ea032ade0a9e14d0c1b16df6bdc385e79405739ec01a0a22554b957a99aba4136d4484ea122562c01b85b96fe045c85b4d051fb0aca1b496c9a859e2e01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002293be79adce53589afc47fd084e07cf4c18f4edf0a82660b143d6af0f48508be8b1a2f5613088aaf7b9bd7242b98fef2d92328f1cc9424f75252df80fbc4501251fb0d2e1b496c9ae2eaba00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000226baaf2dfe9b57c45000f5a35a8d4e01faf0c42b43cfb0f779a0f2b9bbf3ea2cd8057ba951d5816a4bff13705ce46f3ae6ce5204eddf3c25b91483d5ca6a873551fb0d5c1b496c9a37367700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000019933a18e493f7a8e71283411fa48e7673d654f4c9c6631098fbcb4b3d994a0efd24388bef0b7978db144246146bf0c3360c6113d20287f2c2c9b2a7ab610c67a51fb0dad1b496c9a135a3701000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000161b8a845c62d13dc186252d738746a4cc894d964df9e1bcc5085e86863829f326268ca76f5c82f05416cc07e42951af5cf003e350c20c076fbb906e1e4e3e3df51fb0e2b1b496c9a9ea62300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020f537242939f3a470a3eaee4300bbfd931365f4f37dd81c8390b2629d936fd0421469170824e48165406586f6ef63b6944ce58d6923a55ea78b811dab33a19f651fb0e631b496c9a52f37700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f9c236a84a76ffa477ec5b1c1d8ebca4a5efe9a6f882884da064b59b05d5e317b1c9105f53887eacb1e30fc23d0c79abbbdb3748a01db5082bb11b154982043d51fb0f091b496c9af0f8c300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e7fff3b14ebba2653845335a5d2e4634f4feb7f306716d1958fb93b58774ca245057cbc44571c3eda192f76c1614b1f66ad5c3c1000b13065599cf736c46f9eb51fb0f821b496c9a17651500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000144d9c326e50eb1f0c37cb30344514087848fcb23a8f59a60a7bbb3de3be99168d4024293486006ac489282257a05e03a78f600a846c5e33fa831c49482d146f051fb101c1b496c9a46382600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000208669b92deca5b3461d7a0570d3ceab299401c89340cabcab2fa4e84f7fbc67b74751e9034cf5d38e183de2f84b8a7631fd0e66ee4a30ffaee7e2ee07cb9dc0a51fb10aa1b496c9ad5357d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021dee3d21d44f181f6dd68e0405c5d59d793f229f521ca3913973a5a172456e3abc0cfac9213750873e4be08a58e8ffe9c96312ee0267b906240bc626cd11dac551fb10ca1b496c9a35a9c300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025ee076ea0bd5f5c0f34732ffd94698a03ba8017e1ff87039578d20bcf14cc74e405e8b58a7c6e2fe90f77a4c037b62e9b18aec551cb438e67cfe4532be44402151fb11771b496c9a69335300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fd3b6e817f0266eaccf0d65622c6816741c01a1caafac8d99fd313465cb72fbdc55246eccf394271bf7b19735d9b5b2c0a612cc5765eb8b18f3e3b65382ed9a851fb11951b496c9ad3187800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021f07072d615d25b7807a5af28cefc4d09fa5792d029b86a614fb0e622334b7017276895d71793faa079f0b364845c78c3b50ee87d5e4f3bcfe1149eedd565c8351fb12241b496c9a02fa9100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a65aa3b5741550995cacdb16c0ca8fc87725e18d5a02e74f0df29384d0151c0c48632a57e08771c4518e6dda699d6afa0eef6cf416a2fce409804e29a59c4cef51fb12341b496c9a6819fc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022e43c0afd04e2678324f2193b04e82db60f228c9a0f535e9af7e433c67d9ca1eb29a99ffebfb2f3208ed36f7f296cbafad12802093704dbb73b65c3c49e8e9fd51fb121e1b496c9a24360401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015f63fa829c632882b0c6675904b576ab2408e797e3b1d90039d50b92073ca5e9c35508feaaf5cbc6f443fddc769920a01fc4e1e8742be9568001f035d397c4e751fb14981b496c9a7a1f9100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024cc98a77b57e6e2b04c2a80f48c76374be043011028df7cf96cd7236b24259a8dce92a8908fd3910f7e849516b2275b1e2495b1aa7920ae0463ce03cb9aec53c51fb14bf1b496c9ad3218600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e12f0d8504b4bae32d559d8c5c5c81212772ba6210b5c4b502fbc0c2429d7ea3345c7f9f05c7cd5c22fef12a77fb32686433092b7f0345fdecc8581a61a16c8f51fb14e31b496c9ac95de300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000220d3e6dcb786914ba809af7b6dfdb6ed0aedacc42043fab9fd98b38187895ca153d23749562a589b59b6e465eb86fd160b03e9b05663dc1ba67a0dc13d7dfeab51fb17a11b496c9adc862d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000243aefab3f1fbdb4aabfe83e4bd9f0e9403632c004b571b4e3b4d69b803530e33d0f6f22faced9af822a5e4d3f163fc066041c11066ec4bdfb04464e5c5dd8afa51fb18b61b496c9aad3c3800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000176ab515fe7ada88830d30b62002a21547685648d3e09cdbb54df8ae45fdf98a3fe20a7f09462fc5d14ca00dd45a09ee875217a828951245e2ae2e04ce637e30151fb18f71b496c9a33090600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023277a238e4fbceaedff43d8cdf82ad9d4968d1adce911cbcd4bff8cb6ee82f2578842b47c70f73f56cc775ceb93914c683b47ae224152ae6a64837f01437e0ea51fb19261b496c9a25f12101000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000136cfa1049f5857095a0b341617eb749e676e1b2790e591e9afe7be74641054e37d3c3893cbb2c2b8781201db66da1ddd1644f262d501c9c5e517661968a3306051fb19311b496c9a00e54300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002716f5f4498163405a8dbc3d45a1e32b1e07f6fa490ffb7ddbed20781ae290433938b17e84fb65dbe348b0273c493467b5d7c458e22aab9839f7f5ea35c7f59e651fb19ad1b496c9a3d7f2200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001bdc9f009f8a629f7a6de61f669f6c6e01915b71bf8c240a6746eeda5409c4fd6daad6f7d47bd299a7187d925ec80ce2c736cddc9f81d423e712203b66702697e51fb1a871b496c9a970cd000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000018b73c13d261f67df140f85d11c73eddfc192bf8525b7a7320db99a9d0d9ac490b8ef835c5fc63e432f44750c6760dcccc28a792fdd2876e3c5be8c594bf756e251fb1b721b496c9a95fcaa01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025290157fe8f6be2c9ea6891f653eb7ec719c83117d5872d492b1ad7fe796dc79355fce37bcc68c4bcf229c3ec0b7134580f82208dab1ca95267b42a67180c2ca51fb1ba91b496c9a33688600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000169d72ec713093b03fe1546ea9c67ccf35270296302c4dddb5dacf1ce975bb3564bd45dfb748801933814a0675b87815b27c732c42df3ab2d2b2ea349eba4f95551fb1c541b496c9adcf70d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025c28dfde6e29e8b2435309fb662193f231b21fb398fa25d595c88b2446830184d34279da08b6042408749a0ead28477ef1e4c9f74a11a08a4ac936ffc38489c851fb1dfb1b496c9a428d4e01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c1883dcddae23d98e2900e4566cdbe1015f2d521c157432aa75e57b8bdf7841156e91e422154c0b4580bcf773bc15c7922dea85559dd373094de0202b2907bd251fb1eb51b496c9acbb79d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027d7609fa757ec690334f5e1c7cbcc36ed9cda42d81962baa6fb67393f962ca008c82cbc174071aac1a3702e0dd214ca4f422811a168c93333e6881f391dbbecd51fb1fa21b496c9a30cd4d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028bdbeeacd2c3236d80d7b7411b9ac5359d910f3d3f0b50880d79bb24932d8965f5e6d46748ce611f385fd68a2be5a6882e29dba1e539f2cb350b98698bcf25a351fb20671b496c9a1dfaa900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010829016529469fa30c13a4a200ab00975b0c4b10e9ba115f00181d766c4c6f735e891098893bf1c2b7c62f59aa8c03a604ff58de9f494720a64633f90351fcc051fb20681b496c9ae59f2b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021e94496eca95e7a82f6cd2053dc8db71e598b5204dba0b30778157bded7ab727b7c1cff48f29f2f9d43d64e5fed305e94bf1a08770dbc681e3ed84accbc38c2b51fb20a11b496c9aabf18a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011dfa5184717875a38f03ea582f0c6fdf3e4a883ddc61f4dca30519cb0f56ef089ef64bfcdba06505af989cdea44e7c54885e117a8cb741927265de0bd6c846b751fb219f1b496c9a35993d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c8cbd61d21b9535f56f8f732d33b31ae33f00c3235f38a97e52c069cdf756af22da0a6d7238040e15b295ffc8da365295e93ca118caf669095eb520c31b2bb1051fb21c11b496c9aa5d9e301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a19ad5fd8a18fd7dada9264f914dcaaf3d20e72524d1d11650075572aa2094a769674789200f8446f48f1f123edddd95b65f4f166679418cda3713020547d32851fb22511b496c9a2b8e0000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ad184a08fcc7f936a0502a2b47b5e61a53b50b783f21fc52c76b8fd507eed99a5a7f4117f3e96b4c7855d40f575fa1532ff8bb43a6e2031022eba80de30097af51fb223d1b496c9a986a0100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000194de1269525150086613654fe64781e2dec362e2656af009bd9c62d652e8f4e5e693eb0b9770cf286e8b5efb6e00f319c043c53f2a4163d7ba300d2a89c8c6b251fb25d51b496c9a794d0500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000223d9e32219a1d345a3be6d1480edab98f4f54588286c6c7aec190e0d262f6632c2eca7fa60a396c2bfcc8f9212234d17fec035030541e41611320a06f1528b7651fb27071b496c9adf024500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002303d66f836222684758e72fdb2d87c4284c674184c71f4c8fd623b9912e3dacc567794dff61ad787b63fab70ee8d355a940d9ea76c9212da3ab1e6f4279af6ba51fb280d1b496c9a0d969000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000143e2a17a628a03e6ce1e533e2b4c38a597eedce757041f4dc843ac5a5a51ac9a552e3bdec50b605f374c4a4bfeb84e79b04881c478e7139b20c3cdb4e75f1e8051fb28621b496c9ac7f8b700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001880f1bf9f08663b9b692cd217ce74b1f90ccbd9e9c8ba4a0799a46cef5c978e5101f2132a113cbd1a3c3ba564186002dab53f660979ed462ff26d33876ac79b351fb29de1b496c9a58356b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000206a3b40017272aeeeb95ac46bdfefb5d8d7b578354be60dbee110c20c3a187a8840a23c71155245e135fbad2215733f90a368b1e39f1ee934d7612e67615bf4351fb2a0f1b496c9aa48f4600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c6d31a0ee6845924111880827fedcfcf3ff4cbef648102137642f61f114d62540e083feeb0b7af8a5113498e513095b3064c7bbe7071e4ee1a4f0e1c58c0c41251fb2a601b496c9a44a76400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023db8d84ac828b40ee0bc5ec8ec063521b7cb29b837d052dbe8b411ad2fda05ec5e4cb038e29944f6b269789a3b1ca6811be2d5667329300779652953a0a4359851fb2c121b496c9ad1cce900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a107df7acc5bbfe6e07498e965c98aa34aa36733725c9a9e2379efca527cd6abdbdc8e93a2bdb700920458b5dc4fa04bc495ec146be9c76d5b52e0270a4b0f5951fb2d291b496c9a0ab04200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025a9671f9bce69ab8c0889b51682cb10cb9f3f6bd91f38b31c780a0b7d7c3f9ad5b22d17511657ef5559d052cacf6ccf0f8b92676def61d6f60fadb6b221b72cb51fb2d931b496c9ad06f7800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c48054d1f7f375056830b68d3d5ff54fc1da861cbea7197ee1d54d86577b9e02591ee7d6996c522350ee5b07ca0b6125bb8ae391631bca4ff14a7bfa4ea9c81351fb2e701b496c9a5b282300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b04653201c4715b1acaf1110a78689113f3ff942a1a4e53f98196eba82c5aa300bcfb3f952d053f47e31e4856b550817d55aaaf765c8b5fec2ed87cf43d08a7351fb2e7a1b496c9a8f428b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c17e8a4869794417038d2cef371d883d1f78f49e2192e6da64b76cd0976f31916633d55b9104b50076b3fb19adea492599cd126c7c88de1eaf27e47c483950e551fb2e9d1b496c9ab74a3a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001753fb5e0ccdecfd27202642958dfd8531fee7ed6bde59cdf949631c193849a58fd39cbbcdeb3c11c7df69274fea3b91876b269fcfee09212fc1c64ab2325375551fb2ed51b496c9adc4d2800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000231ab1482dd1cff4494c2087a9e80c0bcfaf9676b1835ea862e1562faedeb7f02b3496a0b58faed1683c4f77a7f6dd8488a9873fcd60232cdd779e7b46bee3e9a51fb2f271b496c9ace02ad00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000244c842e62828f21c574ade834ebc26ed707098759c7a0c96d9ce02f90cf8b7599189472596f7e9e277c93792ac53cb092adf77d1921653a0e035138e01d1615c51fb30501b496c9aa47b6a01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000110c254b8cb73d483f34a0bb6adab92ba8cc616753e1dcdc669010c4515d7f7ce1888b2473d90f290f8774f480dddf33b03ad0e28611e743f9fa4914433a4497651fb30b31b496c9add9c6e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a8f2e560203657783c90eb00157084254cd19880bb614dfc748179e5fed706b7ed5ef6eef45c9562a7f9626ab7c352664bf6641ca3b7630fcd511f9ae9306f4051fb312f1b496c9a1150a400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000284f972f56d2052146158db6700f81beeb2b8b00b7832194e764ecf2d7fdea8416d3b160c25e17878f2ea2f6e7a82f734b45f6bb360d9d2cfbc2df54fd5b712ef51fb31c21b496c9a1aa2bf00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e03502106e792b2e7e6bf9b114dbbc5bde0ecf75dc5c62cb5ae9d4802d38bfbde6ae109dd41db4e2f11a53a6a67146bd7b19c984162b4d22f86e23a0816bc3c451fb321d1b496c9ad8b92a01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000268eb28191d1dde18f9f00d563e0a8fb13899cd576e908acf48dfc1c9c3230a731ccd3758e420de9d5d85a1c4f16952a5b96eb5b59ed5108ce388b0c1ed0b30ff51fb32451b496c9aba0e9c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000199ec7a60b623ed8df3088def1aac2510ea9f1054a245860cb1858cfb7489e2d22783eba1c6388aca60823ffc647d45acf789d915ee7df1f17b6fe7e42bbfe78851fb344a1b496c9aad340400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026e066204992d1edd04965264cdffeeffd149c37f73970b941a4dc610e084248a19df2f77f0dd2863413e28dd258c260e205fc686adaf922c0c26b7bbb9fe038851fb34c21b496c9aca3d6300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f7f215d345973da349ec018c691bf71585022cb18cdea09e21ed5a32a02f9f1cb017c73426e3a1e9494ebde095b99a11b5ea45b6536f35af084f15c8bb7ba87751fb36321b496c9a03b0a000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012df2d914f68a67ef3d426eec0bac60a4eed69c276cec591c69caad43dcca276f38628c35a57267c8c7f20b02198edf152ad309fdf80d8228a8bd5a8af86a5c8551fb36461b496c9a4c241100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000109c5dc65caa1de7e77b4e020e35a0bca94b7bc4d7bb4ca88cb89f57049321ed9c21a17b45fe6de52bf9f334759dad30e13ff08589f5dc8863c4d72e2cd645da851fb37081b496c9aba74c600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022a3692165700b7253eeff5ddec958ec5fef3823e2db7396242d5576336fb892e8cc69e2402c9fd0e974893b1b0e3c765ee38a4d52bc7ba728eb1dae16b9621ae51fb37ed1b496c9afecd5600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016fd9c5c23ebe1c4b31d412d12662ad7deab74e239ad1a92e57b730ef5d5e3d1183187af63e0efb62144675ba8312f93b59af08e71b0d8609d62b8a446069b5a551fb38641b496c9ad281fa00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012a0c1dd37307435bd5cce35bc7827a1ca839a2a5c1767e1b532f7712275f23a85ce771c7bb2ec37dec537f469be501d1645de11778b003dfd524420ad30c89ec51fb38e91b496c9a39141101000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001eacf34a78273dbcb85cc5a889eb36d17a4c4dfa1150450cda70fe78e48f81aa9d5df2b7d15d58bdbe9185f7b9001281789ad12be434dc0deef46f5b566fbb21251fb39981b496c9a37303100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001cdf890518fb7850a996c33dc62ddc921bb3f9e72f6c47b5925722e8cf7515398dade01452995951bb7fca46536f7e04571e25b9ac878b899552bf66b68d7300551fb3a1f1b496c9ac23c1e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a2b8a04dcd328a4a50c6f4bb5de38a9c46915a6aeec006d4095392ad77e105601e5fbb91878d774746c082f27de15173ba8bd96a91ac44848ce49cc243b2ae7451fb3a471b496c9a897c9500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023a89308dd54ecf2ea266e95d74b59e4acac7b62feaa0e19c7e1524b568ac3bdee974bfa2da15013b9da035d1b26d94dc590fb9b288fe24ceac6939f0c9a8a01c51fb3ac11b496c9a86d29b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000230bd6fdb263e8f1a8e38e3b9302f758e7447804b4c20d907256dbf74fa7d7ebcc33f619d15b161ad67712bd004c5aba1feb6cbf157532edb2726acd852a2fe5751fb3d141b496c9adb75b000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b9370e1c6878d2ad5def4567eec0d895f70e7c17c1e4865b54e6732ebe10f71afbc3a99050c25029471a47be584b38d4d615460ca0c1be0df44de8a3a9d559d551fb3d5d1b496c9acbf61e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028bc73f1832083c975719933c5a70b5cd14879068204b76f6cd8efce422b90873b5f0119d9ae006d038fabaa3b56c1ce687d472784c0b37efe32cb1ba771aaa2151fb3d661b496c9a970d7500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022cfb000e2f93fb39dcee81a570adf4ebade5dfbfb7e24a665222912440a5d256f75f421d33ffe5dae096a75fb387e9ea3c0ae7c44f1bc98841776f71baf6d78751fb3eca1b496c9a070e7401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000221439764988026634b5f843e24d966f9a8977083ac8675e01b24611760d1adaf2cc027140d240e9bd84fa24c4fc6d659f040f31e871cd4cc76565c8e583434a051fb3f3c1b496c9ae1a21000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002dd983944147857c138de4885a76d1ce30389e90b4656c7eeadd500fdba77ec5478220b2f15987f0e407f6ffd63bb1ca02228e6080984d78edf3d2c2cc33acef251fb3fb01b496c9a84828700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023888177249b603b7751a89a980ad96984b78516a4d75a850da2ebbcff312226dae7fb2a0ba848ca6df7a9c233ca4a66a6bcaf3a32b8b4aca1e5035089037492651fb3fcb1b496c9a81293a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d4be5ed2db51f5116315c15be8d1f4cef14a97e3be6a9ffd18719123f87cee51e928a2f5062465d4bc369377124c9cf3a2d66c50ef2e623e0e7c850c6dc9295851fb40161b496c9a8e3d0400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000107b6a125f88d7dc98b795c837b9166fb0b31f7641994e84cc2a025a45e8ed27c5cbdd75020fb41cf1291a1d70cffb0229dd4712e6225b0e7fa139080cb29c07d51fb40d71b496c9ab8002901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d3129bdf8253f5b31343e236865e4286eaa4c556570a788b8a19bbeb8f111895402c567f58d68fca15dc214173a6cb6c0b04c32e6001dbb15f0df260510b510051fb41161b496c9aa2ad8900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f543e32800d2deedb6fa22d8a0e64e92e35fa7649328427b18094ef671da5986d304d8f6d5eef51f7e396124584fd73e355679025f2ba44a87b71d60c20c86db51fb42231b496c9ac5704e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002331c1a2e05bf8d3676309aaef3a35fb459f45243f5f385502d2e8c7d3b4dc4af1fe2d0b58bd30a0b10f8f0e1ad9763ce3d3254bf9a26b0029f2562e944c6917151fb42371b496c9a41b67500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001bfc07a6ea0f751ec346a11e43d91eda855dbad4ce4c04c57c4805098271388a1387d39a09a6e7e4376f6c91dfc1c6e337a86057d85b0ab05ecde8ef3d268f91051fb423d1b496c9ac4f55f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002abc3b7e951adcf7253b7356d90ad6316cd19a7b57e990ea0e1fffa12b0ba90921c56d5540a55a50018089de672343205e008f5663de54df615b5f765d022a8dc51fb445c1b496c9addfdba00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000185b0db266bff4d14a61117b6779e6f21e48907a825b500445021cf4093694c493b39fd41dbfdd3a1a656296deaa37762b8f9aae7e0f1d7f07aff992140c6c35151fb458b1b496c9acf90cb00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025485a86297e3987696e56aa3f89d837e90b93c2aab587d0b74fd517f85dca9c0361eb9f86b1ff6170d730b19de439b0e6130d3053e7be45aabfca921bf8d831551fb45e21b496c9a93818500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001eabac6e4143f7c0eb95633d9c46ca62eb29ef26739f339aa09558ac405d066b9570bcf903b8ca7a17b3cb2b152b37ce7430c744968135406d81243286f338afa51fb465b1b496c9a6ac90600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d8cb6baa83ae030162f05373d5ac33c5c7ebaee2ee264938e27280951824529784c8b4aa63996431cf84aba0ccf01fd0448eee9ad2b652d7330a9149d86e839a51fb46ae1b496c9a0ffe4d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001082e464bba46e19f190744d7afbd99fcef79222271593312374ff27cf19aeafba4fdeef8824cc05c87c11743947b08981ac774030a69858bd61c7fb91a22223651fb47ea1b496c9aada41800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025358f75bcf89d4d401b7a3f268dd53be28de2fe9e6f501ffe8e27ae76f1df96675e7c74e2f17771eee8c7092f3bbc7112f4e885d3acc89853cafe580bf8e62ce51fb48301b496c9a237f8d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024be0590b7450f23f64121b4222d59ff2ccb84fedf7dd6a8da7ce9b6733a5a228411a3a1093b4ff9b62d2914dbe484e8a7225d60dd7783504868190d3265d955451fb48bc1b496c9ad2563d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015451180aee175304b0258544c1d2fda77215f8274504187e51f1a76fcbc1bc8ed42a0ae899c3a8a2345d5e503cc98e5fa086f1f17f79d63ca6e7758abf2e291651fb48e01b496c9a02540000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002306eeb83de882be7668754decbcb41ee2044f9f0133418d0f9154790bf187826e064da212c026a543b783a5b7d147075fa7e3a87cc81b8d0fded69c46bd354b351fb499f1b496c9aeb609a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024dd381d7c1f2822c4aa783cff254aa0e184f212353b1ecf0ce57eace0cad5724f4005b54f8ef2b6aef3852def208ab719c347312d2ec82ba2b55356004d54eb351fb4b781b496c9a52d71500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017500a7953f3a52b64f89f7f26ee887beb873e863c523b3a0be5ffea35bca624fdd75150fed8e4830e58dbdc5517dab02482bb4a991b92cb4778600d119b06b2851fb4bad1b496c9a0ae87000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c89f6955c67fdfc6d86957d949ab6e3f79e24a74adc70c9cefeb7dc9610182564de94080ae4953240f3330821ce76831c3963fc59bab10a479efeae33c4cdfae51fb4be21b496c9af2f43c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000247c66d117366c5bcd3ab35fd152629e47a514b34273a0079e18fad82735bf2127e975fcb4a458f4438861136a212856f567d17171d5e6f6867fab4ec4cb2f4d951fb4c201b496c9a0c4d6c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e46ac908bc5e4dbf888221952b98cf726c18fa78eef5b7043ac4240796ee961256269838dad8d4efcf849c803a228d958d37c8ce24feb884bb624046840dd5af51fb4caa1b496c9a7c131500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d26266d817158c6988bd6c5e7aae285257cd9370467705316b70fcd25acd3a1a8e44a57104a97043f4c5a0c286f17c8ff455d111f92a50559106c49c74aba7be51fb4e2a1b496c9a4a648c01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e3ed8357ebfdeb6a122ff474a2575dabb72c51d380a3ebdbd032777bd86be9dae034ce7cb6feeaf277fe05f736f6d0e139893650a05060d51830cc7445ade15d51fb4e5c1b496c9aa0861e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015f8203fd990ac4913d3fa4ac137111951a7c0877d081cdb95bab0a9b46c9060b00cf93b20b634e5b8f5f0a0cf3ffbd9436b9556f798fa317769a8efe7b7e831351fb4eeb1b496c9a36156e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e23cc8de939250893286625769c6e2313546b9b2ce640171c7da6ca1cc89f9ba9b6e94c20ac7210c5c331d75be2765aeb888323590fb1441ebf41a44dfddcdcb51fb4f7b1b496c9a51d6fb00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002de5fa73f9672390399aea3b2820eae28a26c7825026984c23799713a45be2ad1a6dca15cfff33f1762b07551b4d0bc3c46cc6ea77b9ee0e72aee70009121561051fb4fe11b496c9afb475000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f6d73f24c0df88de2abae776da17f87bff469a069c715336ec9b14548017153081e44cf5e982746990d74e7c82e677d01855ff824efb9d763bdecd5992e6162951fb53291b496c9a52bc0900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002df2322ab86606d0b90408b9f73d38765e157df3160a785d0c842bae1165ab53daf86cfec74bd59ed9d9fd5ccdbd0b76cc567d4a964e2bfc095a2ad5dcf512fa051fb53321b496c9a44da8300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fcfcbe30914be8ce50843aaebf4f05c29cd534ddb6a24d4d4c8bbc6096a81ea4e6ee0e353e2809476012853a0966aa5c4a049449b35d898e8818a7e4b9ab5f0551fb539c1b4fbbc733453000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000297ca7510273efc50588838d54918c5985ac4fae69114a4cc3b4bfdfbe78787f06ce3aa74bf650373f0cc32fa2508d5da67b98657943528e66330d06f46f19b1051fb53e01b4fbbc786b40900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021267f3fc8f920be74aa98ad406b57f073157351e0b256ec712cbc3bf63ea8cd17dfd390977f5a45d836c9b1c8275156e78b4b38ddbed107da4e2a4c483778c4651fb56cb1b4fbbc7d9f83b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015a7183a6bcfead5dec865efd0b54d59f5fccecdff773bf3666a73f15425dbdaee135ed15a0c9f48d415f3af16bd295d07139c7d64de0fc46df064bfda15fccf351fb56c71b4fbbc7eb3f2f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020c2319af3c770a93aab0aea24cf88c7c5d68341800d2bf54732c42efba94eba06a9fbfb03dc1ff6a200aeac7110d87a530771d3378fb1b6701724a8d41303f4b51fb56ee1b4fbbc771ab3e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002175f70ac8ffdee8f3a3acb2a59d7cbf70439a9820decabad1b3dce6da95a88bfc78a787650a08c72b888a00ad7cd4157e604a52e47cca4e9460433f72590bf1f51fb57331b4fbbc735fed700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f55c4f1c6cfef13ad04aae9e16e322f302a3bb4f2757bbb9b015bbc58d1579f8b6e86dbe9aad69627a7a7ddbd223b6336a50204d8d48dc3c9bb66f798ab0ae2e51fb57761b4fbbc73f35a100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bdcfcd2d4ff26e6c022668fc1b89e23bb3fd840b9a1109f2ff02e3630a8b43b320e0af430e40224199b7163691219b17fb2a18c5a702eee15975d5c318825a6551fb58e31b4fbbc7fe516000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022a6ba28e2664c25aa7366e12c2461e8f04412c5cb29b9ef498cb72eea7d00438830eda933c52a4ae5c35812bf90a03a2ceb6417cb4df3d5f18b3d613f6008a0651fb5a491b4fbbc7fb8a1200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ce0adea980b686fe73dc3a86440be45013c769fd96f7d56b622344d2157d347416828c835cbb0b345666440042aed3e369271168a5b4b744cb124e0c0d705ec551fb5a7c1b4fbbc72740d100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002825665911a86c068d776ddf6d23351b0f20cccf6ded93e94e439d199b7ed17b09fafc8060b762b56695fa5ea62f55c5f6e427308f089b93573ddc1b3a7c36ca251fb5b011b4fbbc7379a1500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000019b35e44f08097960a35563ad066bb5bc0d3a6f0cf1577962f04d8cb6aa8f7e261fbe4b54ba09c13b351bd817ef2eb2e5c38a85ff1277e971964fccc2ecdeea1a51fb5cb01b4fbbc79c4f1400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c78f71cb5e245b48be38485ddcc7ef8259c5b3d3bbb5e03b6ef9311997f554ad341f20be98c27185e44c79e94f1703823b45f3485ec3043ed0be5a2b6c7653ab51fb5d571b4fbbc79037e301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bf2467742f7705ff0f3580fc5934d6b45e51a55dd4f9e3aa9d47f2e573891ac92dc7f46280cb7a80dc0fcc5e2318defa61c2854eff2fc96da80783b1c0e9595a51fb5ed61b4fbbc767a47d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016ac8cf99f7197f3d05a240b5d747cee36f707317b4bbac41e8c895418b94048f69c151e2c518f463aa45cd932674900758bfc32559c44b4f1616f5ccbdcb833451fb5eee1b4fbbc7956bef00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002083cfa7aee0edd46bb80b02b9a2048611e09722bcc2ed55f595c47dc8554668ecfa1835b210542ba94bcb681ae6d8d131280ed2f88112e8b5023e50796b542c751fb5f9b1b4fbbc739316a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e1e5eb72158c9d3d13b20db894fb3611fe248987e97aaa97fcbca68f7c97e163a3dae1652c39f39b31e9b6578cc9ef2e7c11967d7036cb7d64f5dad7df9f12f451fb61b81b4fbbc76ba23101000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b717c928e72fe5714dcbacc87c939ae006d77ef31aed5b89ef9313a28b28142658dcb52045728cc693da029195050a9b710a5bf2c7c1379f7d9fcc8de63b19a551fb639f1b4fbbc7fd5ad800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002313f01485c11ad13c1340667029605ab4e6e654f848778f9a32ed5783e1612c87bbcddf41daf7a2ced0f3b7e72885d0784813948c7489b6fcb1ebb3db897e2cc51fb63e41b4fbbc7beb02500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021b39db93677af85a098f29a1698d1bc009f15158c816f8bd4da2f213f257a95a7030d6e1c41af9735549fff6527db993fdec8b3e661b2820995c6f1a4e69949351fb644d1b4fbbc78b7ec400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000213c6b24c833d7be1bf0702e7a1ad86a37496964888f58f2c05e4943f215864fc437cde0c9bc5e97ba070008bfc45810400d75e65f394fb6b74df1368b36c43be51fb64c41b4fbbc7381fbc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020aee9b4ef4db97059a75c387f5dc58fd00c2720855a22e1a9dba03e9e5ed596c45ed5567e097b7d8be2705d6f1cc90b3be20bc2248043115f257d1e2dc3cbd6151fb64dc1b4fbbc7ada6a700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d8fa226b0ddfc4ea9f668acdd837d6a289fdfb42017ce1702890dbed2cea863c9911db08cca654ddea7c18b12ddbf1daecc5b7c2e8396d5cf4cb266b124d564551fb64e41b4fbbc78a1b0e01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ade13d9a88b4465eb3e6c72dcc016ed582b25af65f5411e119c1833f73caf3bc71fc409eb5023444201ac6064ab1f7e5310bf91038876e9c1c0b148e7de36e4a51fb65721b4fbbc7a9ee3f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001239d7d3b1f850a3b13ba270774404bd6c688d6dd9b793bf32a647d0a5424ddb99a62250692ca02e7856c90a67835c6d0b913fc2d89da4609bf3c11f0e3ad577b51fb65551b4fbbc7dacd0700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000251952d8ab5747e6940ddeb4b89dcdea54276d546373d5d452585b6546a444d9792fbea4a1f7cf326af59f3a936bd92a7f11bfe525337da66d482aa6d3e20013451fb658a1b4fbbc79ff3a201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000115a8840372ac90cb74ec5d8e3475818f7eb8312c50355d5706b3605807e91deeae13bd1cc272324bc3d3bf7cac308e128dae4b7721926dc23915f1392687885651fb65de1b4fbbc78f854d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f8dd0b8f6510579d0728a3a47e0d20bf960b31de2742e057ee479f65645757809a7f5cef6de1ac72df81c67399a6d884fa200f2f1ecd77bd77672213065464b651fb66b21b4fbbc72bb3a700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028d8e9e84770f21455ff7cb7cf865dd069bf7e7830fe9a6122bd04ce00e31482198762cc3c93e5717fdf035daec9ca4d31743ffea81f7cd696a9a635b035516d051fb66b71b4fbbc7ce7d4000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021f7dc6241f689bd3b6a8295f25612bef36b9b95a0119c50c006eea3271f0e018b336ecc1ae749b0c016ba923a26ef84619fbda15299e85d04498416ab5e7c33451fb66c21b4fbbc77e960700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b38d116f53e3178f775d86716eacfc1d0c0874c7170edf5915b5cf871488510143896394c998201606ff8738e0d830f4e9bcf1c98c88e186625fd4161bb2a57451fb67de1b4fbbc727450600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e04dc1b75b84b4be14ef25b0ff12a71a8ef33cf9d1bd0cb881c7d214e0ce920c7d4b9bc14edf6f8c35b4452d725ed1586241ecf769e6100c55dcf29cf3e8a2f251fb68101b4fbbc74aa1d300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000137ca3b3ae4140031d9cdac8c82112f34a4fa2b5264a1dfe06cd476c88e96cef964e0c34d9f41320a7fec5b7eba223116de1306c9cc4df9ca53ae6845d0469d4351fb69401b4fbbc76e0a9600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f34206a6c6199b11a93fa80afbc9016f6bbf85c3b3c4bef2da350b7f54cf128ecadabbedbffea58e9e2295be0a9061ccc025f8066ca3551be24a9f4732a82bdc51fb69671b4fbbc7626a0000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027515e4a3b4e094c8e31309e025df890962afefed76d0c52aed178b7d5065fdd69febbf734faf82053e33c94a41d9786769aed639ac38e3d52e64931713a9c80c51fb69db1b4fbbc72b84c200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000294b0e1b7e50632f5ca9d3d186163b2a06d99f324e2c25084332d0ea01bf83c87b929c6b901e826e3ca3741b3d754ebedc186f26487ea0afacb49223058dfb6b451fb6b821b4fbbc704e90f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d5b9e89d22da8fa73e074155de1bef1d62565a6ba269fb1ce801892f0435bf8333677d97edd480d4add4f9668088066bb54285665435f20171eb05f55f06b33151fb6ba41b4fbbc79f9ab100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013ee76137b6b9cdb3028b9f8e095e287fc1a3a995f42459fb06b88ca87a7a4965568fccd5728d9ffdeda3af2ca8dc212ebd1857bba279eb8d1c32c25dd4fea56251fb6bc61b4fbbc7f5580901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ea834bd7ebec08a7586785b56ad61d820853512e861d24c3315d2a769b4df57ab2d893b37e3c9ae761fc98a5ba8b034c44ebaa7fdd89af3d5072579b60f7813751fb6c0e1b4fbbc7df2bbf01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001cc7378320d3cb800e9965094ce1cb9d24c7ab673e86b431461bb445738968ae692c0dcaef436eb61a9570a62e8f998159e069f773a905599e328dcf4414b46ce51fb6c471b4fbbc70214dc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ea5d5560f307ba568f88e1e1d0b3beb1cbcf3316c3abd41f56760b1ab0d1b7247dffc33c5c31c0beb2670ae668e1eedac983d80cca5f323cc5c7e0158d9eb52651fb6dda1b4fbbc7a514bb00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022ad60ccbb074258be51d52c7db3874b8fc49c01134ea463f827d5a59d77a1e3f03855810235227baed13704a4a1ba7c6f3bf40fbb165d63300206143f58f71e851fb6e4f1b4fbbc7ab085901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000235d84f0bb6774840970c88d43b820bdb7d997f8cdd52924fa3cca9e72222fead460c5da7ab2e61ac3491f7598f7fb7b50997c841a2607bcc19f13458de12236751fb6ebc1b4fbbc780dcc300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000219a2b02a81ac08ce6ffc17ed9dccb07fd277dfe1ceff6d2711a3911e6c7a3f46e158d5c35342e09466b514ac7afa39b7cbfc0eb6cdce1c5cbfe3d5dad2b2fd4a51fb702e1b4fbbc72e152c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000285ddda6c6dccf9df7e7a0c0f34fd3cde7f3961ff0f6113448633915ca0e17e5b432cdee06c80df2b5ff6a905b7205b6c2c60a5e83693c4ba27845664487eda1051fb703f1b4fbbc79d157500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e7ea993a5ee66da735c48accf34d2c49431131dfc9deb84c76e1ea1af8556aecc1770588544a2cb5a03c073b44fe051cb55026b583df02f1dc6d8d7efca0fffa51fb706b1b4fbbc702f60000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000174976152ef2621a922c485e9fe40922e9a58f8edbb43c227ef557d253f02feaee21c656c162fc5643ce3da9bdf392e28cf9a50af57508a932c2d48be2792b2d851fb70ee1b4fbbc78251f800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000208d7b446d7f4a77bdbb48c78b1bb9256fa91571bd858c96c70fc6d6d39a12118ca098b7c86fc09142b66d49cc73a0b2022042505872350e2600ae89baaa026bb51fb71c81b4fbbc745464e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d8613b623599e44988f5edefc315ba60b9201bbf0f337b7f134f01746c75468df1ce6b9ebef5f86d4db9569d6c9fc58f9e567861e2ad40d956b4a0e2c3a8672451fb72101b4fbbc70511c901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002427d99a64de7521bcefce9209cc39ac115ae680f2e7b7cc59c711a427f8ce63781605f92521d691dfe3d302ad6734c7faac43137dcf66a0d244442b5bf6a086f51fb72ad1b4fbbc793865800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e3ab986b11084b832f10bac3c96657b8b1b7555ae068e4f3fe5b8237213afc428c4abe69d7d316da9cba53091a1dc2292b3a0bbf1c11652d039d7361251b4ab051fb73ad1b4fbbc726d00600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026536f92962d806cf365b7ef19e12b844f45d964f1d7791d746da82bc20819ec77065acc44eb247595f3f9719f81b284fcccc13ff74b1aeb68119163a47e3a7f051fb74a51b4fbbc7b0947400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024229b6f20adc0d2119df9ffbe84a153ed5515a949bc504c96c8be725786e98dce2ec763b0a0f46e05bc3b8e350ce8c92cdcd3d6ebf75ca1b46d065975f53a95451fb74f61b4fbbc7eb716c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eef0165fd02c34bee80c51dac8342bc967937fc56a0b5bf6830eaec9526ebf4cf7bc2ef200b050d84fd9dfc70475f1c70c63377eb029d589ee64a4778864f43051fb75091b4fbbc786659000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023cde4026b7d9dbfa793b570394f73bc373d093469e941797f2f838c4b425616ded6ab455c0185e096eaa759c72cde5a57d15f85f79d4174bdbf8f693dd450fb151fb76031b4fbbc7336fc300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e3847c6717376ac1e171b2503741c7de0bb7a2b16949f20475908b07f34861633a2b19c0882730c74a955dc6e7fe59e8c1a99b0e24c8cf7e8f9c42c76b96789051fb76171b4fbbc7c5f55700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b10884a56d6d05d8eab417674c4299d953cea2d680cc61c94b6f2c0e97badbb47ad19c41f9690f4d52d1e848fe959e3a64ad9aef86fc0ad5d056e53e7fe269a251fb76f51b4fbbc78f673b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b3770b8ffa50c08c2b9a5f92f56a28833a6849098c748bb6fdcb6d6384f29e67817f604d07deed0bd6dd83cd646240c2ace9c8129a67bf1f97e71cde6e7e42e751fb77341b4fbbc7124e8601000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000259d8b9dfb3b38a7fe843371fe80d3098a74fffd4bbb1caa10d3babf07afff943756c8052bc1f2bd9925e5ac2d568e3d6660483eb50c1da47535adb03f18fa5a751fb779b1b4fbbc705a8a601000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024041ae098f90057ff81142c9461e8584765ba51d60971ad95acd743853e43a3848bf054b1eb85e3695c40b683312246f2eeef3c1824afb7f17fc70eb64174d0051fb78861b4fbbc7df1e1e01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013dbcb7bbdd9645a44fd8dd299be684787e492b485472da98d42dd3d450ffd625d1a830320dd533f5d2d0a58818af706447a7a67a4ea5ceb7ab4071cc63848d8351fb78d31b4fbbc7d1346500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025977467a90b3b9cef504c686183a8a656169525f1ff55045ec47e081c5c4178cbe39f9189456aa00a5c01403cec83039425f00fab2051c603c2b984ea73ab81d51fb79011b4fbbc76b260800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bd8ffdc53367faffb8d672e23f92445a0bdddaa945032511958557fb785f67befec1f326c38c1638123c4fe4365b2eadc2a9aad6640c3cc74dcae531a4e1bac151fb79371b4fbbc7a50c1d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002614fd662ecb5e6095a96fa68bcbb5149579218128a3ee3a9af6b2a666d6d413c81f452865a4463c35717736a0fd1abd8eddcae99cf3d714cd5bee76bd88fd78b51fb79ad1b4fbbc75a6b5900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023eec953da9e9481dd095df57f6aab7e7a7639574483d5bbda7f6202bdac4f3ed1ebf4c9cbc66d2a34100d8e2fc625539c1f27b6c47aca6f584bc1db35d0a6b2551fb79c21b4fbbc7cfc10a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002296fbb0f12b0a4b786d018b0f692ccc67d985db3341eabd8a2a68ab60cd2e49694151e302ca6027edb805d06c3a80270ea0eea258349b76ab6f422d3d00230bf51fb79e21b4fbbc75c536c01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002391faa79d8a94ab08c05cbe3c502f40cbdf1bcff431358e67ecc22d949217935df21da1c92935e1adaf91aea77a5e3a6dc2c09d74a55bf0f7f5b640c88d6a16851fb79f31b4fbbc753440200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b95e7525587d3f3374d6fad77e6efad66fb81d9efccf8ab9bab408599010e8b01de87b3a66102cacc3e64ab9d7cf79938494c186812ad7d91c955d77f2f29ad851fb7a461b4fbbc7a3e3e101000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e1718ad03d5ef8af4a68cddd0c43b206cbf6125c6ee42231286946003b8b4b64e2b96a0610744821cec36936853842be52da034ee984f6fa1248ac6839d2883651fb7aac1b4fbbc7e0d78700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021772d433ef48449bcd6c9eb0772075b5ed921db373bf7515c01a1b0328ef6dac783d6ae2ec603fe7428f25e6e6fc7bf66c7d823ff65f2706ca4b5ac8ed2fa03651fb7af51b4fbbc796bc3e01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001be2090798ee404c57dd0955811a8c47e5a0d0229d268c79f3359baaa75ebc32a3b9a791299432f0139a49e7d626b95761b063f597d07129abb1d6e2a21ffc56251fb7c311b4fbbc7f7570300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d63da5c56ab5023eb2fb15e944f0e1388ea367035869f38d809e1193bd47486361a7151ab13bcf807b2a3070cb732e56821b24a77a343238cd1d29967ad3678f51fb7ce91b4fbbc788c05800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025c2d684bbcf73966ddad73157822352f5716c0852156668e2427b461222008b6cfc39249fd5e0f891a0f68774ea106fdda47c6fe6f998e94816edd5463eeee8151fb7cfc1b4fbbc70b515400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024f00d1af0936990812872eac1834f5ff35b43e63cb58a3b1e7a7825258d12ffdb1815228aaaa7b520152a42dbecff07d1899730f913c68afa3e7b2487b84686551fb7d0c1b4fbbc750827300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025cd8fc0c618be31c2c2f6b8cc61f0027410940fd44a72f5c16bd395af57b9e8a0bdbb89f2090f60bb791d55a0d4c6529084710d836f24a619d87509e80ccaec551fb7e721b4fbbc7f3949f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000248ecfcf4fbd7ee274ef87837c96b82979045fd20c90072bec043a9a049265890c1e7c6a3652e39a7d9e8171c1813ded7d7720d4719705e92e526e51d302d909851fb7ee71b4fbbc79f738e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fb85642f2fcae0dea56ba0cbafeb4cddefdba348072649c4b0249f706207ede46de69eb940505d1e980f97538018b8d59a2967a0216a350100d0b90244d6a70051fb7f2b1b4fbbc777d92500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023911c311880fc07a9c4b92bba85fcb1334f177f680d6a9b4280cb9e536eab5d2dcefeefae6b85d8185d208fd9c7c8ca2b8b66d28d6ba5f9e1b78ae3e75fd1c9551fb80c81b4fbbc722ae0700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021555df271be6ccd336fee257ca6b0ddd0fcc6fc38c7e02f8764b49fdb2aedccb0aa79f7e9486c00f59a1362283f3a4580cca37145d54e5355caaed7a6c27765351fb80d51b4fbbc778d78300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000019167f923ff7efcae3b89a3e7d5eb6f436ff3292bdae1ad7e57dc76efe12cd0c280ba8fcd7277fcb93f36ef374a8b9c392b810796d5990338bebe73dd3882812d51fb815e1b4fbbc7bf273200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000296e48f7bd83d8c028ec5a180841a90333d8d4ee1c027345a65aa407a7d13cd1939bd715a53d820f557f66c2da2a49720dd728091b68dd62625f776f41deee02b51fb81e01b4fbbc7b9610100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ff81fbd1bb3dd1e622e7c523a280d7daec64814c2f9e627c2c35319685ef7c01338d4e38088187f3fc4071af6d498517aae2abb83cf09f30a6af8c7a325e09ac51fb82bd1b4fbbc76d1c8500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021aa87c1fb78a550e6e6b2abfba3922e9c7d880dbad6844891adb7094b03fd765218dbde8500fca75146f34b9d5be766c950736353bbcd1e76f7c5e9a3cf409be51fb833e1b4fbbc7cf971700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029d351375cba038cacff1dc8bbac87dfcab8746e00e270a36c352c8e7348730d36d1b61bef6e97de0b4b64e75ea11b69c9e0aaa67d33b37392e11a59850a79ff751fb836c1b4fbbc706ac4600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015ee3737ebd283d57af1cd660a414fce24285142da504e2f66b1a145376d6b04c4b8474713bb8e5000d3ce8c9edee7a4604384203d0862058138a675a72f4707551fb83661b4fbbc715cc2500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cb8ad7d9f4c5eff8169bf9842bccb7dc24863d017b7385efc0808fa5ac36e109266e9a7420fa507aa4fc26bf3902aec1d5583550947fb264cd4203352291963051fb83c71b4fbbc72ed14300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ac8a0c0d88e4e9e0a8df644bbf949f49d056eded9676dc9c4c391426c1fb8f31f5662b8e734a1a3b4ee411e26f38913985db6c454d394d4bcacf8ee6ec1fd8ea51fb844a1b4fbbc799482600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b1cc6d7d1d41d2d38dd1035c89107b4b0ba0185c0abe0994b10bb3c24bb381346d3baf173979213f1df61c1d023aa956b88c08a81a4f23e18696693d8e313e0b51fb84841b4fbbc776e40400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000127388ab3d51abad9278b7faff61f8a293ffb928c4a8785abb72a80ec5116b731e107da916c2d34e388b3a4c837c03364ddff84b543e1caf1424f76088a1dc2a451fb84a11b4fbbc754e71201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b2844aab382035c5febc81cbecbeca1a985eb4bd7ed57c45ae78ddc497bfb5c168cf96afae451d4cd3b534a8ecd27482f3a722254669d64d06f93c301150c36451fb84fa1b4fbbc7f479cd00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026db03cd8000f75f69be33a35ea6999133ccff2ba1a30be8c0ea65bcfd02b6690d13e56ad88b15a74eb527a77be6e6fa1f955bc93038cae7500813b82000686a751fb85e51b4fbbc777795900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000214b1dc87ab9ee55f6cd09945cebf88bd8441871e72e3cff48644c7a0a268031dcbc5475458ef21ae4e65a5e54236fe140444db59eee93faf6ac18664c79a0c0051fb86681b4fbbc7a4cea800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bab34f95dc0e9f2b097e3d24ad04489a4bccd916ef14755c27d84445344a1cf888953755d13545c842c6a22416cd6e78bccb2b113f8b99510b0b22e55ff382ff51fb87321b4fbbc70d555e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f8cd44c86647fae19255f06f32f88a6687557ebd43337dfc57216e6dae2ca33b0c46678f3b6a5899bcbc9484bc83b5265cfba7257c0e64026e5785f3d127a11851fb87471b4fbbc7b0d60300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022d0cbf04a676c67f98b543b3ababb18eef895f1c5c773de6b2197666ff8055906c079cfb16f92dc421d191c3ab7f9f89c43a47c2de8654225331f39c6cf9893e51fb896f1b4fbbc74549a000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fea2155835de11e7bac60b4929fe7e798599f4a2926bb487a3918e2c6bd91e8a64d3815f19dd0fe4fd04babe15e8b567c05c1bb420dc8a0de776d2eeb717ea7651fb89bf1b4fbbc7fba2b800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000222c290c72238d664a513d82e37dfa10feaa11167c423cd75b8938af389bd8fd2ea42c9400f7a49a47dca4e8bc286d59011df4f5819f989717acb90effab1348a51fb8a171b4fbbc7fa847000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029048521cc940b5c4bde27c84488662aca8d0510890e8a9d2269c53356c935ba1136a13bd3cc803c52627f28e40382950e81a26aca6211831124e3180fc70d3ab51fb8a951b4fbbc753121300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d6a15d6cffc825544476675884d28075b50a0dc50fdb6325403193ffb862b5927c9a50e3c6cc2a8c85b68bd7adf399fb1c523a60b24b3f0d47c53389a9925a0d51fb8aa91b4fbbc7b3ec7600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000223d790872088e1027779379c3d763d877aa841f4eda66e679ca417a9bc5bb064963c4fa8094f4ac65aa2b674006d0c51960631ec2c6cb35faa066e0a3db320ee51fb8b2b1b4fbbc737b21100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fa5f6482bbe1b98beb9e6dcafcfe49779f7dac3f183f9a23272d94fa62a788649762cddb834e7ded9203c384f868897591dbdbe6a90a238ce01d64a3e1079f0251fb8b181b4fbbc765274700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000205ca9950a567a39f976310593934adccef972d5a1e4061fac29dd22deb01045fd70c3b12c5c1a3090ce760c3decb4ac566cbaf794252ad1acbfd29bb951706e951fb8b941b4fbbc7ed927f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ac3793ac4b6adb931c67bb8b607e79d7a0402632a8f62cf2e91efb48e268496287bb9a80bf425f5a3d0faf5e302c5223bdcebc027470c415a90b1740fece87ad51fb8bac1b4fbbc753e22601000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001aed77879f95eaf13c4e2541a0df50f0cd94ffc3a47d0f0e7efde3647e58ff94471eb59ff1703d4b14035990b4afd845a5a03c37b5f787798e3a86b4d621172d551fb8bf11b4fbbc76d3c1200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015296014f87a38774f1d80ddaaab5cf45781b42808b5a5330b86662991519f14b6510249e1d4e78de8a3dfdce881b4464d2d5a137286c86d3bc28855bbdd1b0d451fb8d0f1b4fbbc729f83000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022d4955ebae1546c3f580380a2a0940004f8cf2c898a9f2ef5fcd8ce9b650fe7258fb49fb197714c278a6c5181ace5da981615c9c35ac88ff76f89f477745141351fb8d331b4fbbc70c816100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c13a0e4cec433e63f3576f35a97a339a8c8e8fac7f4f99156add6f9bea6a570e535ef28cab950e4fd206e2eaee05a52991ee8e4a3dd17606b720d2bf16d49b8251fb8dff1b4fbbc775712600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028e420864f4521836312bd89850d9bb414b2a1134c28a621a196544c92b0d03fcc87a262a81faeadeffe97424af445223bc8628268ee06d08d7a6edffa4fb2b7451fb8e1f1b4fbbc75028d100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017bf458222d532749780199ddf96930a3b5e6606e1913fa1c4cf9df167cbfa099d297e0e896c550ba1be8d73159e86f2ab98ce6d070eb465c21bb8fe9888a5ef951fb8e401b4fbbc725751000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002596baf880f0393f7b49c17472b0eb039425925b7b1f529c53528a735cc494a9a8b86d51cdd621115048f90720335f9b8ca0179d50dc0793548063c05aa850a8e51fb8e7b1b4fbbc7219d1100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ddbb07315423d2a9b1ba40fbb5deb670acb3a33f0c5ab75895d63ce7169deef9a498b7702b57f598747425339d20807807a305f4179c55b85a1e9aa939c1719f51fb8eaa1b4fbbc7db000100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015587de54e3ea4e9e52fc3cfe1e056ffe1186fba881a29626f76f6e507ffef1443a286ba919334e377dfc1b7f6241259e05c16a060c5369ef4a4db34445f8741051fb8f781b4fbbc732141500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000126a1168c5e95e899b5e66ae10eed2f06e590a38f349708f4d7eb6282fa82075a898e0f68d2ff62b41d0998d8bf7a2f2d6fe12c42df579c0bf13720081439867051fb909d1b4fbbc7c0100d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000202a7970e190475cc54e63896acec08e23cd4b93246f546bc28c138b779120e4d4005c5d927c597c9e299bb4c572cd28acaffc84f26d57d07f18b4788f1c5b5e251fb912c1b4fbbc70ba78d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002105ad4d32c0997d2a7a83026f2bf74f2ed3e60500c29c95e7f9466ba458450fd5ca377707c2d9f78cc9f7d3173e4fa7206d2a95a1cf98d76b5f60c3237ee7bc651fb919e1b4fbbc78874b700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001679a2a0e16761db1db40230d23fd9d77da3be40966190b25aa838e7e6f7bf52aea1d4ea8151f3a9f19d964a43f3e5eb3eb1314d5e05072e389e88b9562acffbc51fb93811b4fbbc73f7e2000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022174e28424277fd0bb9e1eb3837ffd8103d953f4d1dfcbfdb12d9a373f49ec3c99724e39610f7a90adc53afbd87fe51c9a2a2e22259c2a8b734f427f95c94eda51fb93e31b4fbbc729ad9900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017daafa6ab73e8918b6b14439912f7ad8af3c45c81633b0c1dd38a4eb16b73dd8ec71b574ec6455f4f5929b73c2221ab3d6c0b99d227b49a1242a0ddbaf50088851fb95131b4fbbc747c36b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002132c3a5c86f4fde36c3a0e3ead29b3258c399aad846f4c4f9408fb09a4e151e3ae88f27ab28a6c6bffa9b9a5c3ab157c3e360d3ea4327e5bd42b3e5a2d01f31c51fb95d21b4fbbc7c005b300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002016897b4b0a60d7dbae8204788e4ccbab940f62ca2b71e309dc5c6ffa80e560ad93e0c34bf962b1967dc06504350fca5d4fb71656cf3126d3d7a3c65611ba8be51fb96a31b4fbbc7649f2700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015e566f36e7ea9a780dd52b02fdce9c80c674c4e96ff60735c1865930c029ca94258992f7fa3cae768a2be503dd65ed222b0a8a58f654033b51f530f546c9ea2a51fb96bb1b4fbbc7880f6d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cd3e0b85b8a02a722b03ab2146d720ab812894b315019ef9cc025993af01d861e174a7b8e028143a4e4a256b18da970303a47d5587fe8a683258e9d97639428151fb97761b4fbbc7a70d3c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017e7262ffe76b2b5c071eb946db059c1c994820af1cfef25362d39afa5198237bafc18a1f246c1c4e8f2d29b48eade6af12658159072d055ad5579cd4ecef4a2e51fb97b11b4fbbc789a30901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025619a502ba3dc33240645189d34e52219fcd0c6c09c09df28e602950280349d118663e1e05ba4ba4a07c8fb8f938fe3ed65f3006dde34eac97c60b39f53b378251fb98161b4fbbc7e0b15900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c77ad562b3af04984a0629acd8a33b2f1ead456ec65822a76bed507ec70bb0bbcc39f7f75d1dfbea6a525281da0e6a07979ac520cbe01c68f5ca4f805e86243a51fb99241b4fbbc7abe72300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023d96bf7b4b7b9accf32e2c8293cf71308a1f55bf2426a82a2f5655950441fa9a4d2a6785b8e48ff0106634d180a406ffe1920336266a78d0561402be89f6a02c51fb99301b4fbbc720050c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021301b6bdb22b8dc01a00e3386653eeb0840ae875f5cea6a1cb19239c82a1cfe04c39e7737d1ff350a9ef48d41115faa347f3f5a0acbf2fb564c01ae3d37fdfb551fb99ea1b4fbbc7dd0e4600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022c378c67d5388fc725dff609e0b9bb9fb346f2b34457aec956b6ce8cfb36915a25a8043f2ebe72c104e19ea8da6f61ae46db760dae75ebfdb6a99e346c9591c851fb9b131b4fbbc73e3b4200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010b499fdf38d34602c1ab35c103485e112794f9f035a78bb5507e0213232c0917afd4bf8deb01cdbc5b1b9b8ad4ffb60c44bec33b3fd4e2ed15a9ffcb9c527f4a51fb9b441b4fbbc7a0229700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022ddd2abb10d7117dfc05dc14e9e4c011cac0205d3b53f772a027c6032cdf4b877cdd1dfa56b64b210d201e9e142ddd0e5625c5e78e2f9745fc410a996a18d55251fb9bfe1b4fbbc70d82cc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002317192c8712e2c8dcee534a50b99143718059cbdd8eb73ade9a23a306432d48ef69c48ad3dd46859343647464d1337094cb1ea5dc682469416ce6f03c193281b51fb9c261b4fbbc72f439600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000113c974c62ba21cf8922bfca9cf5eb5272f40ea03ab9cc349a7a41451156820493f2b46f3c179eed466e55503fbb2e7f3c4c69953f10c62e293e7723cc3dfcae251fb9c2a1b4fbbc7035e2f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f8fe2e5668bd0ed17dcf16ef6bc8ce9807c30ed6412161412fa30cfff02b9652a084812dcf9db4f44797626392f784645b5046959ddd62b3dbeea628724c209b51fb9e571b4fbbc7464d2400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cb03835afe388f07b677b3235f0e56917416be8d84cb5c73d17abbe1d92893795831a8ba4c4de236f565ffcabe44dc23da869c3f267ff3002b33e0b54db4100e51fb9ef81b4fbbc799a50c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001cc791e8194159128f16c5acc49511348e97407cedaf279ae1ba0453e508d8c75abe7e0dc601b4434e0fc721ccfc26553e97e59c2d25d975e0ed5408c37d93b3251fb9f411b4fbbc75cd86300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b0b5595efdf93dfcf72ee12cdf3cd116be49642e9930590f0ec26d6937491bf3893b869dc7a5cf19f70a9cd7e8e71678dba085ee213a79ffe77f3f341259051951fba04c1b4fbbc791ea0700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c3cc2db8952764226a100b513682831bc60efc3d7815c9c64cde0b4e486ec496a2a2cbf5549714ab04b4c3d4acbed524351c115f0c4dd147d3364fdb142631f551fba0a41b4fbbc79b8c3201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d51fbfe7fff6da862f6ee5ce541a2bd1ae5796db6eb2669f69107c311a83d86d698fc64e7fb15eda80ccbfd7bf464266da813e53e1210d382df6a1b71e453b8a51fba11b1b4fbbc771c14a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026a9c9514d0f16c0fdf3762ff72dfbc79aa4204175435c5deb5f1666b2b5515eabcc9233142f95dacf839193f87371fc8a5cb6e69b26588043b156cb6cc4fc9e851fba2641b4fbbc70609ad0a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014d9a5ca9e8737ebc4c4428b7232cc35211c22ee322e7b496975593c4a4924cd4ceaf6fc2216fb40d9b76b6499ef472bd0797ea1a4f8dca73796aec5a11caebb751fba2951b4fbbc766747f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000165a2cca5d24881dcfe1472482f728d29bb8831873bd626a835608fce2323c19c2f72b0fb4e24ff87eaf12b6a4a5eafa6662c2480219f17a47bac8d6430ed9eb351fba3121b4fbbc7c0047c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f54489cb0aa6aa26ab377f49179dd9ce5179d5d7d0ae698dc35057ab51a2b71136c8e4937e3e693c946acf657fd400474562a30747d54e2e259600cbb759e07751fba3431b4fbbc726199b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e7756d613737435cea14e3100b272f292d852548c7735113ae4196051268d81a3f421441f965d784c4ea073fce903e778be373fd4b68583b022a1ae5ef76aa9351fba5121b4fbbc7c3abdf01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cefdecc8409b839bf9b1e11c456c63fdfe40d80924addae8a2d9854e67b84ce8b2ec55ecc605ca37eeefc2f8925e7edb389ac3d113ba276e04d7a6196464461b51fba56a1b4fbbc768d84f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b5a6cd27ab80f620870ad7c41fd1c46a5f64648fd0a99b4b787130515cb1d7a314f2d90ea724600a9e8dec38105a63ce5127ae251aad69534fe224a81a08d65c51fba5851b4fbbc777e14d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002daa63f5e118c02986771b9395f08f257121e713a639d23372e344ca0965c5518153a9d402c4777d506bc72810fbb16d3465c84d6ff49e69ee551b133e26f88f651fba7431b4fbbc73f075600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023e6edb1c4bbf431865522dc0024713d7bcd6f57fc4736cd6d70763d945ada561cf63a2fcce6354eff699dd7928463814bfd8ae96f4a9b8cde976fb15ec01b62451fba7931b4fbbc7e1836100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002644508355c52dd62e20fcfbe3e02234943066d39953bf4b7a2607aac0f33d5fdc87650cd5324ac6d1b98f03254379aafe4234d8ff4d940dd567d96a4e4a82cb051fba8351b4fbbc7a3de2a02000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eb77dbafc6ac8aefe63b85b61a68434047659c4ae3d080915a2e5f067622f0aee22327fd59b78762a1f21d522404d8efae4d54b284e76faef64f3773b9e80ee451fba8ab1b4fbbc7608fdd00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014c35ccd533c89c32f92aaf0d8ca49f79c0238c8a8bf7fcbbcbb28b7287698f60c9a74faa894e500879da3db7d53072598e333aea1cb2e76659a73ca1019e29cb51fba90b1b4fbbc7935fe100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021e281de2f9005c7251b6f8727fc13048e2a7ee71f4dc8dfc210b5b7abccf2c333413e98dcdecca000576d56bc19e2bea8637d05e93b308c5ffc39fee84e8022751fbaa561b4fbbc7ae440000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016eeb59bbce58efc4535c95fa20f162e896440c2b656033fdf308823ef7c31096749e758055219df955272c8f9dd58d9ff48c2e69ce7848c4eb9f884450b712ec51fbaa801b4fbbc7feea3900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a2bb8d263506bd21a04a353cdfd106eefe5ce5ab337f0482a73e6226065064f4afc4a0fa63d8bf8a427e24909214c80e71af062136e49a8fb5e8e44a03c6a69251fbaac21b4fbbc7470d8200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002472b364b1951106ea7abff0dc80411e7ae2fff0faa53b0f58836ea2d5af8603cac3de9a9c2acc59beb28ae556f37ca415b609f36be20a48cec7e29a5ef92bbd851fbacda1b4fbbc7f6dd5b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029d8bab2c0daf0f0e21762e216e248fe045a8be51e1af7c9f863af5d6a4b2ee94a4cbbd0956ee89e5386bcfd678584d6e9ea5a314737f64771d10da131e0419c551fbae681b4fbbc7d6633700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001693f6af53253f1b74af2730431e8abc79a42b7cb17f58b4977311e90a54e4ceaba153d2c21f02c3055b0ba086606d0b4e96f847ca7c9fbe0f768ba068e7fd47b51fbaeb21b4fbbc787b47701000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001cb3b7554dff8dfcf702726a1b31f4de6f957785592c4b1df2d9ff9425a72ac808d1313578e32fcbed24449a525494a4b63b2753c46ff6ed75c246128ca61da1151fbaee21b4fbbc7f7bfd500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000257e8ad950e8cbd9d7e833a63a309d4897b63d36d9f54b000351867dd69e6ab337de10a00d4a6b98a4203a3f56196e2cdcab30b70b307f6a860e31480b8d4d47b51fbaf1b1b4fbbc7dcc7c500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d99b881b382ee9331691994ae571a7b57636475aa65a271b25fb703ee494559e5f25ca8148aded7bd0d76877e8fde91f225c6321d42e84485b880e12d9fb9e4851fbafa21b4fbbc7a4482901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ebc3149627bb47b02ffa0c5f31c8ee0ac5d05fe02f6ee6212c065d73138d28234da68c8947a19ee022864ef5f51147cf04c20135290fc50634489502eed1420751fbb0661b4fbbc711c7d500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bc1a8b657c371d5b12a9cc750bd504f0e1380b3e2fba781af8732b7e5ae1195dc8d57f72f0f1c0b4a10a951269097c6a2c147b18a50e4970ca1b775b51ce55c551fbb11a1b4fbbc759c96200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026f92002be2781c214a970344d4738018a7e176134e20e27f54622b32e9b5f622de483ecc4fe8b4e5aad785fbfc78a8da667621c1897624a3b207ce63d7f49a0e51fbb1671b4fbbc738820800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001446ec8bba58bc3ebed03135e5d375055a1f82e7adfbf26b9eee2f0237b75a4473aad53846ccbe0d7f16266bb4ba80a33b1ac3940cf701935c6de4b4aa81ab4ac51fbb2c11b4fbbc7d0c72a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029580abd887cb6a6f0e2dc83f1a06716a54b22b8225356cb51d7c9bb306e7acc52357bb838d95f15d7c89c0a777c0ad8571d8e557992b85a13343f6695278541451fbb3731b4fbbc7f7468600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f9f4ba75fda4d4583e988c2c1fa88fdcfba8e7e5405ed8f8b76f89a4ab55c19986420b04ddbc95e0e00d5579ad2278bfedbfcfd351e812fe7f4aa766fcbc38fe51fbb3d41b4fbbc757aa2000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000018e19ee9503020ce65dc86f7d2130e6179893ac087db5005f40fbd8c2afff72b5de18b969ee7095d62fac2bd226f1c33dd6c479c8774e5089457c52a5c9d055ae51fbb46e1b4fbbc7942cde00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002388ffa483287786562f7ff412848a94a360431ac86a888f14046023b78d40cfb88be59654a2b108548a394bebada9d5ae4ce39db7b8cd9b001244ea7d75e001251fbb4bc1b4fbbc7ca31fc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002afd0348ad6fe2ab0fe797306109bc1306d08c920e658f1311e1f41693fa44d20eb048f47d8004b8c41bf631ebec165e7b20431ad51c7e27ff2d2c5ba5c939fff51fbb5811b4fbbc78a610c01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027fe7d77e2a2008886f7de21761adb17ae79ec96a945443da227a300f57ccce5ed5949cec00802caea0ecc7dd1c27862f6a79048d75a14a0039ae6606ce2b01ee51fbb5f91b4fbbc7bd520d01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020cee1a96d14e3d39d05beb0aa7b460133a768bd7520c421b0ac3ddcf4f06b9976b608d0dcfba242062219362500c54f337f099c56ae28c06343851a94f2377f851fbb74c1b4fbbc782520300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f74c2cc3ba49e2706c5132f2e12877b22b86dec52525962e59644a65adfaac35c2509258330f77132d9f15aa31d4bc52f905c1436ffd554fb09a0bb0bf9bdbe351fbb73d1b4fbbc7d2c23900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002be7ea4380e2ac34a03e9c1f089121c10783f8569f40f18db0ab8e4b2dcfd0cab48f7633503987fffc481c3aff90e72379c1d3e88c8a991a03d8f341072c5a6bc51fbb7f81b4fbbc7d4a1f400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e51df6864aca2ee37dda0399bb62350f9322258f220c7dd95794cbd6f293643ce63e5e0bca79336b59d8072880c242a86c43c15c14286f46888287e4bc2274ed51fbb9541b4fbbc7a38c2300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fb23c23a19f6c25f4355b577d9adaab7554be82b96c5a83136c9fa1e4ce267433488dd0900b979b54eabd6cd37e969fdfc50a8eca8c6e16a9a82fa2405d1dfaa51fbb95e1b4fbbc7654c6400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026a662a9c6a9b6f62a3fcd82cfac6190c558bba46ae3612c702df1871929c686e94628e9db2c71b1b1f4a02192bfdb985e1bd596288d8061ac753eca6d65f02bd51fbb96d1b4fbbc7d49d8f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002df36b018a1013319d352635d63fba0985f240d8487d9ab6c80ba0ad10be411551fdb0efd7be435fd509edb516d551d3c9622a11d59346ac8914d6843af88785c51fbb9cc1b4fbbc7f9c50600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b4fa8e1709dafaedee48c527f468bd5b22dfca33452d800b6331537cdc68d8f28c4731c6f1f8e361f8d206894e0ad818985bf7e9fee9d75c82a5ef29c596761251fbbad01b4fbbc77777a901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000128259fa424edab7a5a7d49aafc54ea5c6336c283f4cfe9e35386ada69726d66283a3e83203651baf5faa520b40f464653be96f59d8288fbe022008ca5852949c51fbbb181b4fbbc79cc0c500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023107d11bcb157cb081131dc7fb8b39cd5037e798625c38cdf74bd65b8b91604e81fc03477dd793bb168eee4450aaf722ff32e8ec75aa06c8968d0993ab675b6751fbbbb11b4fbbc73be54600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000268e3a5e291026e8eb07f0439e660c3dc4c000c6b2db59ff6b93af3fe084193f398fc471e23792ba86a62b52d5cf81ffc9d8189cbcd662a3b10d9f3a8aee7517b51fbbc771b4fbbc7521c7d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022d36edcbca26b54cc215364c68ba076e81c119bf315ae355c24c6f5097e01d2346153e18b422b2a8abc783f3624af00f333d0e584a027099cd82e2f7185a784051fbbc971b4fbbc7b8afad00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e92bd0a1a954ba1c3d1075eac5eb391b8799e48fbaa7987e7be4696c2cd28cf786e1b14f880e5ed26f78b895b18124faf00106b6cc63c63343fa94be30b8923f51fbbce51b4fbbc771cd9c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012c9926ce60e72906cec5ab517db155981fa2f967bc3defceae55950cf208d638b649b35c08db054d04560c50a42642c835fdd66c6a5360a1d3009d648292684751fbbfcf1b4fbbc7b83e0100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cc1caaa5ed5eb19606b92d8ad1c9c8d8ad1a8cf011a36d8b8df7e7d9146309f1ff3484e9ada178dad2a95b7a937fd2e409ddbe02f096d952fc5ebf077b9fe42f51fbc1291b4fbbc73d320f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a2611ab55f42975e7b9a6aeb361f77978848d7b09764ed26af233b9c3e51c929cd874ece617a382b9b8c4d5050eb6abc511488918a3409d7fa1f4439b3df6d5351fbc1491b4fbbc7c27f0c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025255308ceabca68bbacb4134a5de727570ce8c5b064405047c6cae05f44999d7d0d057263fe378b2a853d9a26b3ff5bd1d50f3c46e18d3d10e253b3517f947a351fbc1ce1b4fbbc7d6e6cd00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000103e198828495da471c4a878192bd85cb56a2d7cb8e3db5d1864f714c0f33ca2837e84abc2a8a65b15bdba03f396755352c4cd50d4ef8b7bd87442c67e887e23151fbc46f1b4fbbc7b5348800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001850ce1a269a166b73e3f287d49ddbb20503c05c7f6fe26445e506e56ffd65ef959dc0d7989468b9333f1db94da9dcf5160ef6e82ec13ee2c8faa5c48343cdbd251fbc72c1b4fbbc702970900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002708753d0cdbe8edc095b7ba4027570925fb4af7b0e241eb6b936f3c80db1032c931e3edf3b0f0a284d0c750bb6d0e90cec9865459dc342333b7d1c576e99db0651fbc9bd1b4fbbc7a4c03c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000207752d8923d6d28de6f2edf72fff8653d3a77f95943e80ed1125c712bc7052c29ad6a9c5644bed9fb95f5f162301d69ea6cb3094151ec1a53ee5b6de3c1e78d251fbc9d31b4fbbc704180000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002547bbb53fdd30ac456d2508e3778eb2b44c0c9849728d37d879a670ceaae921b0cf70d063fc385edf6ac948930ce7adb7c65cdf5e4c532e9f765103abc4dac9451fbc9de1b4fbbc746851100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bc0ccacf557e0c2e7b185bba52bb7cad570e0b6009983d9ed7ae736155bae32230c317d7c9b342244f82cef0cbf5422857b3628ae4e3f4afac683aafbd0f157a51fbcab71b4fbbc7c63a3100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002030b478aaab45c1291f4b38fa3d8475615521e11d95322d57eedcd0d955c61ec3ba3397fb75733c510fe21dcf41de318698c81a1b34b062ab81312a9a9561d6251fbcc261b4fbbc7dca2f401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021b1208defc49de80a067866fb766eb0524b3d0a996894fffc830ec1f737e96d809945d46d2e736935245e9dcfcda5f142faf191834b62e024448f9adb4f9211c51fbcd051b4fbbc708a31200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000230d0a797adaf641305c023b075b10399ee1d91ea933d8c12bab4a3a17cf3894778b7bc68d325b87e00130cbefbd982f19c8e33a18b6377a07394479ba6b97cd551fbcd3d1b4fbbc76e235500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022fad1fc78ac162309ad324c9cea67964046a5bae6598ccf565f04c2a70ae95b6ba9aa2ba57984575770fef0833c99bfa5cf00d7b56a669add1d826d972348be251fbce971b4fbbc7cefc3f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023d653171e1caedef6b8b9e4b1b871b405aeb5e3d50581033cacd6907169e6fedb1c6c8ae4d572ede5969794b244add4f242196fb1a97dff515c447b625b46ad451fbcecd1b4fbbc7ae39d400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015f6b8cf0bdb32a54d18a77b037fa2baa431ec3de09b216435f1b2ac8ceee1c730b92745c6b665ebcc520e591465a150a35887edb20202df3ff5f6e1f95d616e851fbd0fc1b4fbbc758166a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000218f494e1e3d01bf981935050fd373f819dc8464837a5f32eb3aec787a0056b9fe401d431b881734482d47d6f9bd6a5a2d77bfc52d1132e3f755a2d379fd2307e51fbd2ea1b4fbbc7eba64800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001dd36df5bd2cd884d0d09a48f205f4d8b903f56210ebd4f0d0357e0b727f078600bf0ba0c9fd959bb39756aca897a8e7751eeb7a7cb77adc7ffa57026daff8f4f51fbd4991b4fbbc779938800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002aa1d5ee49823e6f7b47cff025cc3c21aa6f09562972269a3c54397fb3d598eb74ce0c6497bacf4e316f1dfe7058e1274146bcd527f0fa5fc8c46f2f55bbc82e751fbd4f41b4fbbc7faa70000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027a197822daa9934937c37f0a091ecd8f1c6906ffc98acfc77209811d62822ab751ad1acbd9a803fbc16138fb8c8b5ccf50b71812dcf41e4d44a792903c259b0651fbd5561b4fbbc766027000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002280d99601f57755fee8233dff921d47ec04ec01ef61e1119c752c604a3e2fe2cefab963c4582c8c5f343ad8a12ce9e8038179ccdce5bfd146a1438d1ceb0d3e351fbd62f1b4fbbc77846e300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016c576ceba82e8947ce9732b025e25d62f95c52f13cedb2d24599b4038f507d6600f5dd08c92a21b589af7824a8495c96522c9b84eddceb7b32bc926d663bcfd251fbd6361b4fbbc76178aa00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000110269bc6ae6bd414bf62d2ae3748c3b09b06412ad7adac4fb1abbfdce43e6983e25070045428c3aa4a446abba9b29c8263d221bfc9939e59dd5010a3062611dd51fbd66b1b4fbbc79a0ccb00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000174b8c0696e18b783bd837057595417b34ab1ff0b88b0d1360f44dda780a3cefa0325a0c1fdfde52e42f0c9e82cdb62f0785e756e9654bbc3e509f2f21deb09c551fbd6851b4fbbc7b48f0200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025cfa2b6c59f64ccee9293f1d8b4ee37322fea29940a93fd1ceb10037d56bbb3808ed20848d9b9dbf8829c7a1a7e5c912a2c9a9074123cf19a9c4c40bfadced7651fbd72c1b4fbbc7e1370100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f556c64beea8ace730d42c23dc96c8d5484d96ed74052f575e5c27fc7bc6f56f6eb281c812768e1ba7fc423ad870f5b121ce61932d281b563585268bcff312c551fbd7521b4fbbc70e787700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e665c75e8963568022794a370bef3e0e3b61a096e27984573cef0521cd16df63884a01743bbde1a99bf104003137ec1cb2aac804f34b14458db066809355bbda51fbd7831b4fbbc7ca54ea00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000282f134280fc1827255e29d9ac342e5874471b7cc0edbdf977f983b80b0ef5c7d8c2cb6c0189154003943ef64c79d725ae4c175fb43f2501369ff117282a2315551fbd8301b4fbbc7f5ef6d01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e918e3de1cf65a2da33892999f03d90ffb9d350e2268e7f5a659d1f7ee04f5efb9e7e8cc9b72850a9e6b8e97abc44076b2279ca9d3d45e2d9eac383b6ae6d82d51fbd9041b4fbbc7cd977d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002453ffde278eb27817683699248e76dca48286ded5ae690a1824a1aa02e96d7dc477b1ec232a0cc265b5ad7d236ece4c26b7457fd873441a53c8043ace8b24bfa51fbd9811b4fbbc7053fb700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eaafa3f7ef4ce05083eefdf0d01d07af811eb7fdbd9566c006612185e01c6ac7fd6cd0f54fcca548c8071b5ddc4d27aa645b181f179b2559ee2ca60fda67608e51fbdb4c1b4fbbc751594900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f7c4fc2af4375c00cf82bbb21a98829708a0c13d5f1e94959fd9dab24133a7ec95b4ed0ea414c9dd1ab1b57172ba91d8deef0c6eb68bfc8068cb217302e0822c51fbdba21b4fbbc70f74d400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017469107f16f9a01c1bfdea3297c817f2f69283d94ef570d5982c6c715b8220ece92743599757127c3bb0dcda9348895195cecb2b22565edde825f90141469ffc51fbdbd51b4fbbc7c2862a01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ce6c0fa9f086c757a8b8c36b03586f79815bcdcc60f2ae0d33252aaa2d423bbc8457623d9b0e4ea1b677f735b1c2aae8b6c9d431f3f040e7a0435fc14120341451fbdc961b4fbbc7a09c2800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029acb0dbd409c3e7cd0cbb8ca0a2f7eaacda285f4da2f5ad2cb5c444db5b68048a4325f9e5f7ad4c67d678f2932167f2ef9b3e82a4fae79d3c85da0c338e103ca51fbdd901b4fbbc730253a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001125b647632bc9c40554385c1994bb2a44f84b2b6618c21749c4306bff0079e4c5b40a0c77f7fa7e536ddc6d89d8e2f772d2028fc0c7d1965f1dadfbcb39cf2fb51fbde291b4fbbc718d08b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000200d59cf7f487949f88c842ca06059ea15d8f3fbe19d5620a74b6b3f0a335750ebee694b53467d6c9e2effb5080dcee6dbabff7dab3e4a1ce9df54c0c7aeff01f51fbdedc1b4fbbc7dff81c02000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eeb103a2d7e1bbc3587c083be7d9563af49bd896bd9acc88b8eedc1a84a16945396d172d74842e190b0359a1b59a332637a79d4c8c56b25888745b00b02dd28051fbe03e1b4fbbc719100d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014d6ad28a31195e44f0199415e077bcab4886eb427d7c034131e88c410d16cab783d4424f2b09734bfaf031cb932162ba020715964b674f7c1016a3dae4ec3d5651fbe1071b4fbbc799314800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f98b3a93f55981910745b8a998f4fd9fa5b6359ebb177e0ce6157dbfe9e14cf7b8c2b9155a57b668597ba1047d98196da21a81d85d7b9fa644c8bac1940e084951fbe3781b4fbbc706742b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000266addc405eb0908ee748e2b80d5ed8508cbaff6f9415d1bfab55ca47c183eeba175f1c802b3652b522936715bb26e3ca3fc9dee9264f7c375ae0faa53d3e9c7751fbe4da1b4fbbc785336e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000234f239b78513b39b8bc9c8f09db3322b7bc4e73297c9b445f98d62da9706321d4cabae013f334b7403c7e4da0da385cd7f599d41a845bf3390340fc58cea51e851fbe6241b4fbbc720889201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022b153e8dde1574b488f55594870f38ff0c4ae654597d514e63f3930ca614a8bf9b9815091b9ca443234fddc84a7aa72210cd751686c0fb2bf552e7f83167376251fbe9661b4fbbc705a56d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011d667ded56b535cf58d9bfd854fa4684437828a6ad9712d4328d65e790b92591b5d270220e0e233a0a26c71c4ee7afba584515c9af7f81d9787fd6dcc8575a4051fbe9851b4fbbc7e9223f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000197f649c30fbf001a55202b442b0980b6e7008288169cd0add6e62484f55be1fe688cbd5251bd1a03a13f09d2323fa2f9409284d1af838592e440b57ba2af082751fbe9de1b4fbbc71ebf2500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028f318c8037b6191cda8e68bb050820987b900b27c82b23a0d9602277c8a96496158de2fae5462f30f270ce9da927c93b83fef2b5ccdf0b1260cdb7b60e15d6ab51fbea001b4fbbc775015000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000216ead1fd19f7c0458215e95db02fc137741bf2de5a07651c67a892af2b0fa96850427b7c3f2c40eb33d44a57c86eb65fa100db856610d3caa700d9ae7ddf6ed851fbea341b4fbbc7b4562900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002df18ba5ed8c4ae3163fa6a52ed054237a7e3ba3e521422c977ba50a64bb953ec62f470552a5db223942f879807af822231f45eaae953806855b938e8336cb49151fbeac91b4fbbc730e40f01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fdab163599d8a258bcdda78f0e01145f782c474bb05b649e7a917a07d567375921c54f416f1248d69b73c571b3b312dd2b4cd670c4048b5ba2db14de429fcd1b51fbeb631b4fbbc781277200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025318b7bd282e1072dc29ab499088fc5a1e5d23a5227ac8f3608be8d03a8410f83dced9f1d42e3f83f01d0c14a0b6af2ddb2fe3c6b349e1f529793494dfd0199d51fbecc61b4fbbc74b68ca00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000273c95ecda982677883b7be1b35b7c1bf1f9b8313507471188014199e1eea24bea053fc957b97ec0dedc58214ba59c85c01da484c5123af7781b1c7ebf21c482351fbedd31b4fbbc7bfdee200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027d87a30e06a4eb641ed333ea199282a995e8a653251cc55bec73d0d75d6664e5c5f6d7e27974f1dc392db26cf96321e52e6a1e9878888cfc5e2ccfb397aef5fa51fbef521b4fbbc7c2eb4500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000160c68e09686cac1f10794755cafa18e476d16704475abf1e28fd9022fd30b71c56fc827cb9833a75f8b370bd1db3c68bd709aa165f31a3d61ec9b4e76eb2350b51fbef8d1b4fbbc7611d3200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a9f37982b7053c1609a170d9cea69156a6f0ffa1a1745c8f4b4cc0d21432935cf0f874574ff33467348d3b5074fe7179a62bf7b9dab551efd68bcbee773a33ef51fbf08b1b4fbbc7470f0500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a8bf769d34ba168eadb7b3427341fd2aacc69e591bac016c48ed1abad56174330d8d919d1b2e7678c21b38d9e530e1f95cf867054cf7ae8be9609c23a419aba851fbf2121b4fbbc765566400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000145223287333a744e0aa40a4717dacc63a0d6342539586fcc7d77267bf9e532cbcce887b91ed1ffcd9a324bfebf70387a329aae556fac2985e1ea74e1bda2c2e151fbf3031b4fbbc78da81200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001730275b72abe8e51c3af1c69d682fc4532151e0a7f03492e5362e41a8255010e385a1632646cdf24518b7b4990be6def31543c6326c61ae7f536ea531fdbbca751fbf53f1b4fbbc79f292500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000203acf8d828f4e56816bbf1d7ea55dd1e62d836761a24dd01b238dd386a4cb4b08220039a3e35f147af32f318838e2aa75aace749b44fe31fa53bb7b98c32e50551fbf4f01b4fbbc7d7b93c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cea54b00218a4a3a68526f35930fdc742bbdd74c5156db94778cc0dfde0cf2ead0671d8308dd079cf528e5df6b890066d767435f0fd1c49ed76c225bb1609e4851fbf58c1b4fbbc79d4c1800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000018ea2378d16423ce13cb171d3d4894c036bd0645e07bb05f24ba7d80fc1475d7839fb821825e80b155dcf5e5ff31c4b2d1dd53679fcca3c05cd7e37f02aa52b2751fbf5951b4fbbc79a2c2d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a29f98ca04379d969abe94cf3a3ee58393bfb82ca332722a59d0bf2689d402e74ddbdd56eb3d5a7aac9a60bf28fcc24750940d19a685670e400cf718f5fb898151fbf5d71b4fbbc74ec61400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d87f6014428bf0ca70f55d3ad82e809ce5c3765b661acc2b66bbd8de84ad489cdd0adab7e3045d3cea7e76047bf5174856fe31dbe853a20b939afd11d443f0bf51fbf8021b4fbbc70f6cae00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ec2e55f537fd2d9828d33c43126364d8f2adb607aa35e249c23e450cfeed96202dae26f102a99f7ba5001afac3c6e8ce1071a359c197ea32312799be86d4c16551fbf8a81b4fbbc7f4557b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c61304728385a88032b23b1447b7cac349cadf191b81fe1e0a5efc5f4aeb4c1b4bceca64a41c0c9cb91ecd7a76d103e23b1bd240f7da0bdf48d5169c2365ce3b51fbf8e11b4fbbc7c5f94400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e38408261093d020c6f1a7edfa58bdb3d256a493e20a821f60fd6156c5e3f1cb794e1e609f72a787fa081c4af7dd4ef3d0661ba3603f477d8a637d7bf3fdfdb651fbf9151b4fbbc7a5552301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f8999734fa5067dee95ddbb70bc84f4f7379bbbec8a66c7df24eb5ab1cf53c1bcadd1452c897681c67d5aae8cb7916a0d3cf75e9359c709d1822d13dc4bdbe1a51fbf94b1b4fbbc72dc65b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001b1fdc51731e112dae64b6b7343c7a63a1f826122a7493adc4eeb9ca28d29e3ef82eb96589efd1774050477ba994d175c5ed9dfbd6fecaa695db252f3cd6cc0d451fbf9e51b4fbbc753f32a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021c0e2bf7bf48d608e7318bb159a16f184c4eabc2559cd17eb9395be499a5a8b8455916d2baa9c1d4c08899f2876187785b9a24445335063eef6ba0b94cefad6651fbfa231b4fbbc789014900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001da98a239f63a88e9ea9ec30837c08415ba511f840d02e074aacf934ef75e4083e0f1bbb25f51124dc49b85dbfa342cf574d77ac29b4b3d5f26139dfcee61443c51fbfa301b4fbbc73a880500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e96a8f8ea81046d328e5aa001dfe615d0c1a331e7631017e3f53e13821ff4cbac21350e03784677be13b7183442ec5b82a7a6f7c9389a7d883ab173df42f865c51fbfbb61b4fbbc716936900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027b39b568332d3fad2abe0325263ac5b343edb3d91926766d1785886bbef8d2ab0fdc9b33ef57428617fcc16a450c4233e867c941d6d1ac555eba9419b085881751fbfc3c1b4fbbc7e4682901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010ddd5b30a738514bd95575f91fa5d547fc840fdb919dc326372ed6f91df06d8115d43110d3c55245d640ee6b30154143ecad55d35d592e618014b7d78176043151fbfc5d1b4fbbc794c99f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000256222b661a2b3442227135b8baca8af3136f42ad67b2f8fc6f21a18d4622bf0e31a85c138fff4fc00c6109891dcd7cb0cc8dfac1e2dbc39e6e9bd65357fe48d451fbfcb91b4fbbc7ce414f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021abc32aad81424e304ca3520862ed1faed2361e4e331f1b93a732340c354094a84472bc541e35403a4ec7484ce2d818a5c29fea987740a03cb23d1983d6b637251fbfce71b4fbbc707e40100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f1d46d3916ba5176d1c670f29cd8a0eeda3324e0f11d1544955ee0d22d32daeeaf0051abfbe58306b684a069b9a26a66bd0f0980998067c5fdd8fcee1fbc466351fbfcf11b4fbbc7cec66200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023fb6d7444f7c3d59caa774e7727034c66dfbe19d9613ae8ffd6beda236c65b158c9968274ab696978809b9acc0f0f1038e4cee681c21f3701eb10c3b3230370251fbfd331b4fbbc7e1bc4800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000133b7a18d9a640465e9b4d796e5b8f3d5f97c311e6972e1820fc601fcb9b875c0916961efdbdd82cf54a14941542c25f2244affdbf10dd14031d331003ac3268c51fbfd301b4fbbc773681000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a184d768a3c3065d194542c53c407638d6a0951d0c9c864a2467252015b97757092cffab52de63d08b19088f82f4d5f3c0f5e8b3e56523bb458878568a9b3b3451fbfdf51b4fbbc7daaed900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d490921d0281e36ea2fd5fe055a9e40e426764f0bc1ac92aae56d9f9a4a34f28e2a65d6fcc3511de7a656edc0345619986f5738f13a4afd3179df25508817bef51fbfec81b4fbbc7d3867100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024a747ecd3d711a0a96f4b6cac20ee5d51e0a93e961bb615de4a1b7edfc64c85b5536037daf0702fd9a774a8cfb5dec855902eefb7da6e489e9d5cf37e466c76751fbffd01b4fbbc76ec45e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d39dd9bafed9d25a20430163987dd2839bd5f182f7f9e4613c8f46954eef841323cce6e8009e2fb27aed8f5504c4c9eb568e6ed7e4349204d7927e97af5db1a451fc006c1b4fbbc79c3c6c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002feb2aeea2b89dd128968a0463087be7590704e7700db20e3f06e7e18e31be87678f48d9ce0cfbe4d5c742f1245c1b700e13a1987e185b79a272877f21811e96a51fc00791b4fbbc778011700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002968e1207292f4377d18363623607f072cdd16af6c54e2fe56fad04021b2e6b1fd29fece2090a8504430086968aabdb1195e3bfef83312c5c30a568aa616ddad651fc00db1b4fbbc7eb391e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000227dcd6cc8a6676b49fad0fd85978afb75d44a3438d220164a3f89fd08c60f218196fefd1d795584cfe7e7ec1a6d14cc574921d7936a43274b46ba7e9218136b551fc01901b4fbbc76d3e2b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000234c3e84dc92fce371d6a795fc90b2993e58ae8fad0f2aaf25f44e78b597ea385cd58b28107d8ea286bf6e455159f28a55605e91527bd6a12474177338945115c51fc020e1b4fbbc7194e9c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002be9535debc49d16cfcdef2afc76cf5fa1d31d8bc9e9ef3e578bee80d57fb2244e5e9fd6fc5185a661cd16fcd16c7e7c46689cdcee38b49f3c85690e08dac3a8251fc03ae1b4fbbc76e608200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000194d394b370c956fc1c7439c03f56f502ffa4026f59d6c43e5322d5ab8f1cff40118c5cd76aa3eea6fa024c98ad85093db947684fe0508d2aa3862185c248eea151fc049a1b4fbbc783ea1501000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021e554d7ad056172e9ec8ef634536373e11ea540bb56f0b683f97d99de751fae38c4a7b15830826a22c16579e8f1d81045ac06a2b10a8c5f2b353ba2811d2bc4451fc06891b4fbbc7b0e7da01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e13067bccf6e90487121965fd1e95620922dcf80f0ee5f1c42691adbe68758077895cd704adbe311f22aa888357b4c43b7dec9a4a88e58feffe0f04b3a0a021351fc06ba1b4fbbc7f7765e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001592d757746878b00ea2b2fde92769bcaad166a9a9a814542ee78b285a95843ad6c81e89f1b41052a3566097b3ce9cec5f2a1a509b9651dbdc7fc7d0648d9097251fc06f71b4fbbc77fb56300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000019519c2364dc837c6793045510e565ee27062035ff61f1dcbe9a792ffb21531886a47740be802540f872e45e783d6af3712d3128604bd09918c6704348b40404151fc079d1b4fbbc71d347000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000249aaae727b6db11c485206dc9e181bb7ae16c76185cf91cd9717c1a0ba22d47bd2cff6941285d543a6c376242f5b687c45e1fab455efb25a62c7cd52e498f1fc51fc09311b4fbbc7ae730201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001600bbc8f0dc105f6f4f09ab4367fc87d52ccd75bce438f95ab70b9e2cbcd4bdf2299b02707c90dd75206ef1c506d73e9a9c0337894bcf8743d019a46d9a9c17c51fc09631b4fbbc75c633a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025edcbe328df621334817706b7f2d1c752553043d85bef650db47002075ed9b84268c787b4e9e879b954cf737655e9462fb89060cb0c959eadd01606a862aecf551fc09731b4fbbc7c9309400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c4b99593a7082210ad42894efbe78e952bd9d000ffdcbdab8b7353da23f15bc79b42c8d8ecc9d7f202edb22bc5b7e73deb7a468283c12af8f13c573b1673bf7d51fc09b01b4fbbc7b6b5ec00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012b4bd237258aa06b4b6d72fdb3d47bb95b05d1f44751e2a594d9aef3a0bfb03736e21e514464c839bafd5be3da684dc46ac49105628a8b4c10e21794c1c19cea51fc0a271b4fbbc7eb8c2a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a85f65c6700f7d410a3cf160e4ba89707e4dbf9e1232474b30e526e7210557af36e9b4cc2ef8582f57fccd1ad6054fcd412f1d8384983800a3f5d8556e8da9ba51fc0a551b4fbbc74b9a5400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017dcb0247c739df76bd9beb5dba410ad3919008fa98c7c762e00029b518e31bb65b488c553b211578f74a8413dc98442fd7763740c236cfe4ccad85b9e0cffad951fc0a8d1b4fbbc76ab4a400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002262ef1d8fd476d82e87dd1cb4d514a18a5343e71c28548d2b1f592bae42d0bd2bd8f2856d9e4a3dff3d1741d5a04a8f427051199fcb815de96a722db9a6f85f551fc0ac91b4fbbc7b9425b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ae37e00d39dae29915137656e01bdc6460b6d31dc8b30bc587ce0336c8fb50753ea57b1ae93814e5073019042c4c640af3dd8919b26854f8ae5f3e9fd984390351fc0b1d1b4fbbc72a8eba00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027e40d5afa962c91503a7417357007b91c7791aa2ea091fa8a5243243dc2c1082e799b938d3dd3c70794f57584de26b452aba46fe67d2b3e10d9aaccaab47339851fc0b1d1b4fbbc758f8d300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002448f736300544214b0becc91fd3fcc36d2587649ea74d2354943fde9ceba5064f71932f23993fc6d805cc3497382785a2280e9b08a0eca3e7ec86dfc0f3d002251fc0bac1b4fbbc7c23baa01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000269c21975f4993ea58c90a251f6f193f4efd693ae25d410c93a6ca369e3311f03ff74c551f7310071210e1d4bc27b862db0aad4e19c9843312e4a00755106b5fb51fc0c961b4fbbc7c919ab00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002434395c0ad61f993cf193b997ce708700f82b42d97311af7cb175da12327baceb52a2d52edae604b67da04f744e0ce7e016e8651c7b6336e27315cc54c8b1c8b51fc0cc61b4fbbc74b8d3e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eee8139324d26b258ac145bf296239e8faf64109ec3cbe1ce7d458fbcb4676509b1ee404328e33945670766f753d4994dfee8ee39d20863c129ee9d570bc255551fc0d121b4fbbc74b930b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010fa832188d772a8e337df9e71c741db45fc149baf70d0dbf70920fc8ab5f2dd94a33552fc6e5cc2d426daf9f1f1356df1ef1e341fec1baf6e6afcdef83779cca51fc0e0a1b4fbbc7749d2300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002861b94ceb7ead428fe2bca749b134674c5aaddbd8f00a637927843fae191529f97122e6b6712d04b9d090ce0ebed39e1016872993bd91216fab79b31b43b2e1351fc0e2f1b4fbbc7bafaf500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001cd286528f251f4dcd4bc2fa5dfd7c351895560af034bed78597bee88204a956a060ea43595af49a8202ba257afe40c36bb002141d64e84394d5ebe88d861fb4151fc0e8d1b4fbbc782194d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022f99593c31de8f39fbf2f9680955a136d7f1b4e205b078a3825536449eab9b7dc454c9b71fe47bc3cc6a23bb3a73b0de31463d91d741907af67ab29ba32b23cb51fc0ed61b4fbbc7622c6000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f80a11883aa822f7fc9051c89827f24fc435bbc84324151f9a014f313be126db01e1b46ea5d4549c718d63f9da71aef1c19b4215e04712e85d2055a43700379451fc0f4e1b4fbbc7f3fc3401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000268ab18f3f0569c020e8d8e157c65c367c7a3d59779ac41b5be2d21444149f6041e516c53cd9ea69dcfcbd2739361c8f2dc5718cc8c4eeeaf5f123fbe077cfb2551fc0f891b4fbbc7e61dd700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e0543752cb48c61bda255fea13c86d75a1668360714af930ba029c2b65276182a582714a19490bc02a00b65486239c11cd48ee2ea959f33ec151e2d514b33cc351fc10511b4fbbc75b142301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000277919086626f6289fbc4155838b9383c7c925b0b7dedb1b08055f40dc74c10db493a29cc0f804f76dc32e5cae8d8b8cbcb2a4409f8017d5287c288870dc4c80251fc10aa1b4fbbc70d480e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000018c13d7cd91a7c34ae7df1a89e286e6ba9492b7ad69a6c159d5f8b28f45329b541f17b35392c04e2e1d191ae1d3bbb2745cc273db644ffdbcd2dc95aa42e3546851fc10b61b4fbbc725433e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020f1436dc20075e835a4e67a5763953151650bef1cbaacbc0fe767920a93b60b48da78e24cdccd7cf0cd0d5dc82291c9d1b96491b0b74a159c6b8936b78fb300451fc10fa1b4fbbc7634d3700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ea65d1da891b8ac39df9be472882dbc1cf82df53f57f9912c0b75ac03a885abe3348e2f7e90d75813899c63097c2ee4ff553e79aa4f2bf884904917fae3fe08851fc11901b4fbbc72f714300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000105ff89f931b3b773e5f504bd0bc27e4718f343d3de5751a55d8d782a42d9000e04dee7c91a93b3b1defa51f94c4f953c95cf4fa4ba5eaa250167b88851492eea51fc11fe1b4fbbc7af4ebb01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000233d14607c6472a682eaa051f66af9eab577b78df30376a29175706a6554d0cf9d5e115d14227d14d84e160957415329e0dc181878ddc4fa28c0899070f8b832251fc12f71b4fbbc7b00a0300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020ce2b5417fb009729f04206a6a592a0a210bd184b8861332f322479bdbfc5c7d0e100ec5af3a92bd2ce401dd91fb8ab97b6fc6d2d5bbe6bf1cefe64ad23a977551fc13001b4fbbc7b5275900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fc5a705209458d7daaa5982dfeb06565db7e66d8b5e00b88fea2084071e4e68475413be38b92fbdc094caf3128db4a761e044a567ce4bcc20bab7cf59ad8ed1d51fc13221b4fbbc7f3672500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001602f158b33e56149dbfd251e1ca54ff3d0926ad4daffbf0bc193b5f96b3b737c5ada8780bfa6444c63099cfb9a0ae6bf3f02851e68f5689a9500b48818e3e64b51fc130e1b4fbbc7c89c6c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bf18f26d17d5c71f231283ee9cec3eb5b55f8a8f853e41d60ab95fda7fe6e8c51af82e69770d0fb12188efb61a54a94f66239972ef17f67711713b34e0f5695451fc13dd1b4fbbc799777f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020db57b9a217a5f88f0d7c1fc455ff334be16f9e08442cd0f36a43aa04d4a03bcb117f7c0dde828a1478232306c8e007415558742ba18b43bfada3f6ade44505351fc15661b4fbbc76e845200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ffa0cc5e8bc6cd0d1afda6e18bb1be7aed5f4011e81565d42bb0bde1a384587d9ec59bda7c0575abdf2778d76a55836c6721f5c4ba7d2d0cbfd7ea1b481309c451fc15771b4fbbc7da943e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000018334e55ba914716c204db908fc3d41823ab48014d406c2bf62ead9bf259fd8aaf008c7df94ad9d67fef779966c6fa587e8716b81939a72f75c2adbb89c450d1e51fc176a1b4fbbc7c54e1e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000247ca8ed3676b569234813a5eac2d2b1c8f82e6a4958feda2122118ee2cee432d036e18b5ebb16013e0acce427d63d113caa0228c4e6d0519c75a96bde7c35fe751fc18ca1b4fbbc71e5c8900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000195439fe0868afa2c5f1217b68353490f67c33b896220dd45a5836f42953f1019a5f100993ed90cbea782e8ffa29e4df7fb79cae7f0a8f098d2da44b3382f793851fc1ac81b4fbbc7c98e3600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012a0fefa28fada40cd8dd4dd902f6e0d07c3f63690c59a8a44a6f0034eee2dab85a0f08cc70ff6220010c033da45a5f546d04e6b8c61c9541f64892c2a9b12db351fc1b151b4fbbc7555fc700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bc3f36621fdb16db50b61becdd8a637d435362a197d88315bb47f8bdea99777da422983e03b7dbe18a5c6726273a723c32e087b3922ee5d8ac2b9031cf6cef5951fc1b4b1b4fbbc73a170201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011ffd9493440d238d5f4a74809c294695cfaaef0cdd649a75a6db5c81745509cd58e3ddbdee927cf12343dedbcc6f8a88b2466219c505102b7b2339b18768a7ce51fc1b431b4fbbc7dd81ba00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eda054f8ca19ecb40811b5dbb9999fab9df2dc579dad036a976e31e751955042dcd22904b7246c09b7831233b727f3d91bacaebbe69ec129419fca994a813ac451fc1b9c1b4fbbc78aba0f01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d4e915ee9eb76d741003e6b136da03f2f3f9ecdbcf8eabfdc75c48b4b81d54a419f0f06731d648ec2d63c3580ae2dfa89685221c92d81aeb9f0eefd91844828451fc1c7d1b4fbbc7dbd75b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cd56229afe4058890a0c60e9ca963830fc181e606a352a49145396d89bfd42553f2b9530e2f6f1002cf736fe3226f898c2d20c44eaf269a7c9df1d54d5d1723e51fc1cfb1b4fbbc717a21500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002495b16debf20ac44b4588d18db902870a660d60968aa01adf48709285ce3622b5f6d933e26630e51d3ee7b75cfec454a5618626a79b77303705b41b1b0d9ff4651fc1d1e1b4fbbc787132100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002051bf315842205b4f3abd67c8be1b48cf77f97dbe03aa347bb9d6f32e618c56a148ac7f1e485d706b4e86f150be0ac441a3754c8dad0622d423092e4e8eb83c651fc1d841b4fbbc7e32e1700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000257d5d84a032b61b15ead28fe7a6c13b7681eacf2210133e78e20f2f6dd7ae6f3d7551df6ceedbf2b3d11ee906effa6ad8d42b778f81db24644a74f06b7a3e72d51fc1d791b4fbbc7e8b65500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e20312c9df104a74cf6b3979552f88bc854951ea62860d372c854b8cc28dd56059bc19139f843169dd1124cddc4f21cf98b2bafebee62684f99b13f61946335451fc1db91b4fbbc77fde6e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024865cad359f0a7ce190793d0964708777d2d38e66b9729869ace8ac990d65802198c7153d56ae45726f506dc5439f4280761c6a317ae4c56be1095524577d90551fc1e951b4fbbc75cee4b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d44d982cbc86121bfd55656ec63001e292339aa4958566e57594c7aa83b68abee9460e6c5e3160dc4986ffd388d5e5f3ef68a217132da30a70728ea2da85ac1551fc1f831b4fbbc72e69e700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ccfef04c7cccaf109adfcd612b9cb2930f70291272b47d74397c94b9230ea8e083fd7642ccb3b57c8301ceea9c881c5fa614ddabcd70c5db46b562ae292dbb0d51fc1fb01b4fbbc715330300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a61bcb13842a8099a85f082b360acc2f161794d8dbe1cd8ad76bf73c43a29d2f0557f19117b1dd5332fd510cbbbf9894dc75be649963e272187763ae223882a351fc1fe21b4fbbc7b734bf00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014a3a0dd594f01247e21926a9bb5bfaf9b72c4389fde9e928a79a9dc9a4fc82cf92f10671ce3980c81d6bd8028733da180c3fbf64ad348f197ec1394ed47b93c151fc201e1b4fbbc7da84c300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000294a9e40d5ba114d66fd30d96c668ab63f99b935721465fb8976a5703a8d02a20c4c81314bef816755ec83a5b043c3d36e864eeaaa8e5937060eecaca7fd32d2251fc20ed1b4fbbc74b74ef00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028ef81b9fda16ccdf4bf1aef5ffbba5e5ff093d065176aa36f876ae51d65b5101e78b2d8cc53dd1abbd2efb62af30b77d3afaf6f9620e53abf26bd13c85ff168e51fc21081b4fbbc794157a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001af98c0de72285a8ef8ee7592754f2a9942898597517951c0acd4cb48881bf90c098a799de20cfabe8ffea206008054c16d8bbb7ff6042e23e8124112a83f310e51fc21691b4fbbc7c3071f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000177b50499a11514d08e33c3296108e5b6bfb39fc3d267222e370484aa65ecf15090edb75430038b5542a1b0dc8a33fc01830bb8e34dfe5f063dcb2e75e1368da351fc22271b4fbbc79be0c000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020b5b76a5f561d4c0fa9ace95f5dd70d0b5c5840570bd171eb18f83b1e1a3b9d3d2427b1fd1efc823026335607b67e65c28eeef81c53ec2b71abc504f6a0eeade51fc23da1b4fbbc709ea5d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e2466225460eff30f05e6490feef390fa496a735968e59c4b1a1704151b51854831fdb536a155af8b96d50415cb79cf2c0061c38e6fc4aadba715ad31727ea0551fc24121b4fbbc7a7ef1500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d9a4d0221df0e9c2c35dd72da7b1b708d4b294dab004ede16bb148d92fb239ab78b03b09b0ed35f3390d78bbdbfde8a938aeed977dff87b7b6972dc2ac8c084151fc25b51b4fbbc7a2045500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ba8d353782262fd2e5789643919edf4e6a9de2decb6fcae3804dc8a62f1eafe5b2d08021747ec79e02535e1bebe0cc31ffc3f684bfecd6a7a778ce188d0e925351fc25c71b4fbbc79b117b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b75e49d21d7dfe752046ed43ff6750e79be9d55edb81e658ca87942a24ee80cdd550661323a17529939fd9a1f4968dd00684b69e7ca650877dc7cda9aa9caee551fc26121b4fbbc78fb60800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000201d619addd371422052b9107bee3ab1590324e69719d0636962cbe4e68843c0a97c73dcb545e2f1c754151835cd8aebe3690f5cab006ed57e9c61da05effa61051fc26f91b4fbbc735845500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000264a92999823f2c18284bb43477a3c1afa31f6a9a3c3167ce5e236e5d2a73dd11807c42d454cee626375c3b66862fefa96465f7eaaec808dcfa18710bc7151b7f51fc28921b4fbbc7ee480100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028b0016404a31db356e66a60dd090ca0dd35a4372b08ee06b769fc61f116dfc7fd82bc37e44184b5a5b80d6db12b5525f155763a324777992fa85882692f47a1451fc28a51b4fbbc761b99200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000255dc9a5e65105bddf433573e9c6994b57468041affc2565d37a138c26c3048b236ac3893fcb51fc0412e87a4a4c20beaf7c59e616366652201085f70d17cc99751fc28c91b4fbbc75ceac800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ba376c9ead1a3f77323df9461f0c98cd3d31a68f636c6e231361df6080683ddc281172de278fe3194ac13e67b70438417103cd443148c90144e227d218fa1f0c51fc2b0c1b4fbbc7d82e6900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fed4ce25763f31a17660b87ba8da3b5b3455fee85493392fe72b60d64708033b2e691e33a98981d687c563589f14404f3293631aa0a9712a672cbcb64c60368651fc2b711b4fbbc7257f3f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002532480cf280c2c705aa71eb12a4773993ccb31173070fbd7c80dc69772c8de4ef4391e633b8dad5c52785e089f39ca7607a644331718db7373a2db0a8c4aba8351fc2cc71b4fbbc7f28a1800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d0b46df7dc4170077e88dd1dbcad4f128b56757b5f325916cacbce2e85f3ba383a81b673919ac08a995aaf061501e59584ec0367a62d07351afcbf6193d192b051fc2d781b4fbbc7e98d4d01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025be58c20b4b0080161cdc8e423ba2aedf6787f2c0918bfb43fb52b43f42394e4e30cd0bed58dfd0c5ccc6466e8fa6fa80219ab624e0a8e9b002f215f42bdfd4b51fc2da81b4fbbc724d24600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c911842d0aab161be03ca31daf540d5df987c75aa90dfcb7244bd1d8ebdf28d678b4532c26cd9eeda538727632d15b0e7573feaa37e737583c91405718494aad51fc2e331b4fbbc7a279b900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001dd32bda431b4430d658762cdefb1620126402113b56c0d30e88755e5f46b61a030bdb7b227490b71397ebe6bd380c5afb95833da40854084d5263d56da70437951fc2e561b4fbbc74f55ef00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026e94ae9b0e614063b5c4297ee58a919dbf4fefd68ab0a00ecfa339b3ebf47d165a9aa85cc48d522c875ddcfdf3881366cc0db90d364ed815788221321d37d30651fc2f6c1b4fbbc70b480a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012e951252779eee245daabe49b547bfb1fa816acf7a5aa9488a402ad9a044d237a59f32f0fc2f4c0da1d1e6c8a68223e05d625b85a60473d0cac30b2f50ae42fc51fc2f9a1b4fbbc74c4c6600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a02fd444e6afa1cc8fe197cc3e2f585dad968066c5088ec65ae0b917ce3d49dc09b5c1b52b9d8cb0aa0afdcc24cde7699bdb5999e4ffe39aa70da53de491551751fc30461b4fbbc7eabab700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000270eee3774e254311c65d08a0dcca21ba9af4c6786e6b99b03fcb7663fdc1c0bd8017098f823db128269a5b2fd213f9e40149bcb3fa0033aa92ff88d089c7426651fc307c1b4fbbc787485100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c259141fa10750f93b3e4c5aa0312e20e556c5701f09e6c3fe31a796b776e4c736becf3c614a4cf41a18b91b3381a72f08c79effde68a886563d728eae85e05151fc30c41b4fbbc79d803f01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000298cb57ca2c95019a0a39e8c22bfd0281d9edbcb1342d47655701228e9ef040ca22f271912fdb43070ce11f4668e271be23b3930e843054239322a03419e1e5ac51fc316b1b4fbbc79d05af00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002982949bf2979785eaf777edf50056683ee31476a0d547106cbb14bde74bbecd396193daaab5db9a21ec55a8d14aff71037fc3eaad67dfbf84f2b57c9e739574451fc32291b4fbbc7fa644c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022350b5fbbe3b47acc03f6d210c621c046e2eb1a25824e8153e60b8595ff0d1deccd90529784ae263f790156bd0049f7ac7055f4df7fa34f77acc4138b9a79d3451fc330a1b4fbbc7b6354600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002109a213a310ab44315cdd2a94085c89a54daa463324c8708cab35f021f4eb98bfb13e0620bf590b96746eb2c970190d9789832eae11005efd0162dbe09a2cf2251fc333d1b4fbbc796c3e601000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029e61ee04523695c15c390597af0eca5671fcb6ac000f49f0d39fd8149fb5d101ec864c3fc3bd53857d2a3f49fa088752fb8f1936907cf60067d80dfe6cc8acd351fc34ac1b4fbbc7a75dbb01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002169587272f2169fb1d1f17af0f2bd5b349cd341373bd4fc58d09c22b49b99d2ba62021de6071df89adcaad2bf3b18b00137e00e6c8384b0e9e28a93bba9ba85a51fc356b1b4fbbc76c1c9100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026f00f953e9ffe909eab2928003d440896a1034544f2534d2d2ccc493f56f1dcb296235af7b7baf12af790348ea64ac7fe807f3dd2fbd6bbbf3f92df4c65cfe9c51fc35831b4fbbc70a61ae00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020770bed95751eb7753783defa6b1af28830b94a9c5168160f78860cabdf008c8e816eacffa84a4fa213e569a9b60ebabcf423be7dad8dfb28ce98faa7107fcc851fc372d1b4fbbc7ddef0101000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000207af9631edf9ccddbf06d5d55ba88b00f4fae8cec59cb94d1caf003485832126c140631b3c45c03cd6beb110194cc3fc41f2742fbb200f59420663f2c2c46cad51fc379c1b4fbbc7898bbb00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d1ca69ab631af249607f8603baf332ec51ee91c0205c5a020d4f65168f3fdad3684767e44963d5a14fe12d88ee8b897516c40288cf722e62fb7e010a8a82e1a251fc38221b4fbbc743089f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c7d20aa6aa9d29868ce1c2ed0b56c4f2fdb372f87708bd0eb6ffe7988203684d44c79af88df88d22eb5d0eee8bfb8e31b0f45b90868f36fc03a6a9f1fbe7443b51fc38f81b4fbbc7fe0b1700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000252c646be709fbad244ea02ae0c083fd590641162aa0ae39f69c8ec6793262f02771bb8fea356d3317d4c1c53433a7600518bfed6e66037720e087cf4572cef1f51fc390c1b4fbbc729c0b500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c693f1174928d24a14da4d7bde09e7552a7620c6d6d47d64354fbfb1d95e63cc54b7546b6a8bd3ef1781cc84171f18e8c32af43f4b6e5dc252c90d1c81a6e18951fc3ab71b4fbbc7d9aa3200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000201dcf922a652e22e749da3b8ee8a253180c663b723cd88316928204ce6bf9a629ac3eedf3073d7d84d9a58e680e84a7fa593732f6e8d8759051e185d755fcff951fc3b0c1b4fbbc73d38ac00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000254482faabaf6078feb2a63d47e92d043dff51d138dc952fed98f857cca8b26255e67d005083c4ec254cfbb07dff06e47b59535d7f0b430829a9cccfada9aff3951fc3cae1b4fbbc72e844401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000112659a710b52c6c095c444779bf9e22f8dd592b57eca025eddfebe8c1328247b91a1e936fe9c03b3d61f58a30b12a192aeecf05f8859f227abbfe421e445fc8351fc3d8f1b4fbbc739020a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000187f8e13ec3b6c13bba515fd83a11e03d28fdb29befbef63d28065c2f89927b9d86adc8b0a68ddf8de87f9e07acc2737734f0ab4a82b4c300f14eea2b0457ff1751fc3e4d1b4fbbc72ca11701000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014e8d8ccc885b5e62a941b773420be5daef4e73ba20254f935e636858137341ecd4d2a5e01e5beafcda0e8fb5eeab7d7aad854616b30dcb4eee2420b26d22b0f751fc40271b4fbbc73c890a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c8fe9e8f3c20719045518bb6a8e7ae68281fa0181d8ca427d0f7a1815dcd3d59a570516b9a8476d1d69746e00e7020584855e543b9547b80a692be14af627fd151fc40231b4fbbc7a26e4300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000239e43291de74cbf285b2ed3ccee9400a54121ebaea960ecd9db3490b439286a764e1de9a33bb14e6868eb8c0877e50360f808cd2f41cda4ed9527e5392961d3051fc40701b4fbbc7a2665c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d4a780e3ec1dfae9dbd040b2dc3050bde9df04973a1f22f05436ec5e2e2627b45394f08eb4d7de8407575fe0261dc996800a3af5941b2c7ced8a8a6b3e7acb3351fc40931b4fbbc7fe3d2201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d9dbf330513da2f86c6c86cbfba28290e367b467f38e04c5c54ba2eafa37c347f6c0b07e4aeccfdc432550f88874b29804751567eb7a09011f464137b3a2587a51fc42b31b4fbbc72ab11600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c15bddd0b1cc9716dd60f28b5ef6544d232372216a102d36837d53270843cb0e5b9d13167c0f409a76f4d7338b1b710a71fd55c27a05249dde3eea28fe0204c751fc42c21b4fbbc7749f4200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f857ef7d1b49cee41a4d374363ed9af31541ced81076909c4a2bff878b2f434b09de6eb8d96b60125058928e892e15ca9df887ed1cbf108bb7f57b7285c6f34451fc461a1b4fbbc7a4319701000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e88a8f16ee62f4af3cd7938346e12cac5bbd76d46983df5461610f22d1947564f291c007fb78c1b349e77455937ee5a77721c40ba2de0fefeb8aaf197c2e4d2e51fc46551b4fbbc7d744bc01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000140330ec651d105cd3128f84ef8d5e38671fec21c4ed4c250be035b4f1662b0ff55352209eec8bb2dbe99182584cebb524bc036cd43d20e527cb4d6da2ef42a0051fc46771b4fbbc72e788e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021f088789fc4dff2b84392b510c8ab0d1bc9cc908377122c2e2825d172955724c9a8226ccce60ed7320177885c24ce428b83c8b54664eaf89ace4c7d1c46ca60051fc46dd1b4fbbc7da1fe300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eaf84937d0e61281b0393b7e53dfd2aa806114202bb52dc78c964a531c1cc412d0b7f195fad1811ba16e146951b43736d9e8985bc21a21ad564f1a1180b9c2cf51fc47311b4fbbc792beba00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002960ac965563ed5c1edcc15696102974e00b14e4aa2bba7e9eef416f616ab7addfde0caa8c0848988a1268c286970132ce92e46ca87e2422160c09e1f53bd7b1f51fc474c1b4fbbc775b8cc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f60948115d581b90ae1003895142e8bea329228df92ed8f2bf5147161ae5997e3f3a7b4481e8ef11ae0d63f237f2ea278960f22f5b59d32a3ce3976a159ec7c951fc47c81b4fbbc7ea8cb400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c90694ee72838c346839aa970919afcbaece43f0cd801f366d10c469397b03b6ac19ba7520220dfe9efab2575c295ec5b2a80ce2e6d1d649170bfd9b3da950e251fc47da1b4fbbc71d194d01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001654a879ca169f26534d4b432884036a674d7001f0022c70d313856c1872e1ce71a2c61be8cfdc95686e6777545eee273f1bff86ce6f6022c123af954b36057fd51fc48131b4fbbc75ff34300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029f9f4b666df03bc9e1a011a03895092c535df7b1e9d5f1f1b8ab2562336ad7d73393969dd494ec5637919137afbed80292b8bc6b7389956913ed842e06f3761951fc48211b4fbbc75fe1be00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f3592d0d112a1ec3ada2ede340279039a629f55f89ff6114a88459f68fdfdc73665980e3c7e38c1695f347fa48af2e3916993a4d2df841909ae2b70487f4e45451fc48c41b4fbbc79c8d2b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f7cd07e89730f0efdc9b2480d6bf8c03c4ab83116e2fc495e5d3c3367f83178cbc044d9aae79df2a460e48c169b1c9766b3e71d27fd1b083d895621ec8db5e3651fc49261b4fbbc7f5808500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021f7d154d609d35c577b22d21068fbe876713c842b593386b3fa914d9bd27a0c3be3bd29cd06e520c125adf47906f746a50200108c0d2d03e0d7e41d13fd0e6f851fc49591b4fbbc722909200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001846ff3de344c2194934cefa31c5fce813820e64345e0ae95e9b8cba37658fb9a69692873bd1ff4f644877830eccc571b8250fb22bec79bb616e346c52d0433d251fc49b41b4fbbc7f2abad01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012de6d57e5f1f6deb927c4d6ecece4b3c0f7ca2a38ef886e330c3ea04d03ea731950e91afadd97154e58bbace500ddf38028f1a535e679189b5c130e82734fa4c51fc4a4a1b4fbbc7737d1300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f3b809e9620388ec36460d4bbb674748282dec81642dddc7442b9a011f36216bf178ad0252b8259028b888ddd3a97011c1105554edeab3c214418a63ab5ac74e51fc4a6d1b4fbbc7d5548e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000271f3cf59e514128a891a0324fb1d3610e4cc32258374a0878d76e6b488932dc80de189aaf8ed11fe44aa22ae9a4b6e19eba8da5f7c0f5d3d90982c58a754372551fc4abc1b4fbbc7eaf56a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000188870f2dabe6e5567d964d971a5e01c4f46b467688609f0369a481053aec9230f3bc3daae6d77185b706f3ff62f7273ed14c0c8dd0d941238fee0d1fed85023851fc4aba1b4fbbc77adb0100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f51b001b5f9a19ff496a0aa16f3577342328034998ce64bb180bc8f13c4e75073a158e4f31d01422ea8b9800c903610dfae4c48fb2c6bd3f6db5f47febac2c1551fc4b311b4fbbc781ed5c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c82d87dc18a947cf6cf9556e96f93848fc8ec255d5b707909661e7dcff9cb0536f3472831d969ef862798de804242ded6549383d55c70f573d74b85d63cdc07151fc4ee01b4fbbc70b666700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021e6378703ea4f8cdc19af8622544a5cdf2e05f6a91b423b1fc7921e9bb82d93f80f8394ca65bbad42488c7c947a69ffda4573083b34f6a7c228e49deeca3dc1d51fc4f671b4fbbc71c80a300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000176acb03909f8137330eb7fa9326a02e32beebffab5013c5fd67aa2b5384609ec0ffe04b7cec8c2dce4ddbe98cd4967cd5c8d518d64de03304578f81e741acd5251fc503d1b4fbbc7f2a38100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000200bdcfa7b71f47b999667d6efeda0f24b38f41029adf157660ea944a8aac2cd6f7c28cdbdf4d2166e0e8b3ee6d1cf707858f3b6f43c11a9e47ac18f16b03909a51fc51981b4fbbc762080200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000150943790fbe5bc25d47887d65f39a10ba6c658a9065cac9f3a75535d8f01304670432567d851f00527e4309a3f6003a5c359e6dbc12d332d04a89616e1896c7051fc51ac1b4fbbc730c58800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001bc40238f53d779424091e9cd3fb72233d46b20f4ff0e536cb687496d9b1e0d4e8b5c8a1d1345252493e628cc646adc7b2623e214876cf7c5fb537b452d48b0c351fc52b01b4fbbc7e4b1b100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002308e13939622792a2e780b93d44bd151b542447fdce2a7ac6b3f4b265989d32696d35a22299807ae9b52c67a277af69522e111e1a43fd40d71160a7c594ec3ae51fc53a11b4fbbc7865f8100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002daa3f908ab3a3c49dc32194afaad9e023138ffbc6f6936265c1a08b4d3889979b6e24176221f1198b1d82a04f94d06b4e6d4cf1e98e583e5a7324b07ca10c2a151fc54d71b4fbbc74c924600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c48104a71bd99e8b2e0459be9536bc6bd269ffad3a604f34e8bd7189182eaf14a6a39ba5edef9d2f5f39e5c5e572d9aeee28df1a2a749140c1c17d4f263432fd51fc54e61b4fbbc7d1503300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021cc8d4f82ea796d9cc47ab42975836ee12582e8fa65352c678a8890781971e50d5d0eb5354ee8f48ad916a4c5ca1bf287a3d0d20ba2aaa8a73c924c6458c35d351fc552a1b4fbbc70f2a0500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a2088d2e43a8b6b31bd71d0187dbf37288b166625dfda47239110d0b3354fd22e07dfea507c2bf10a943a4bce98ab57cde5a168489b87ec13b2c4544fcaf032d51fc558a1b4fbbc75550fd00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a5abcea565038b43150d06ea779d0e503df7bffd6f86598b10c2831ecd78f285602bd7e2b442b4920a4203db567f4f7835796ef5277863b40160add1eb8277a751fc55b41b4fbbc7ebb27b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002dcee366f7a56e4fdc0e1a93153726b60219a5a80cb4f87dc58670d39e9999ee87be6c70ffce90b1fbcbda50c5f61bbff43bc648a490c32550565284b09ed648051fc561e1b4fbbc7256b7d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e3a780bb5991707cc22125369daed058bc51e2bd13490518cabbf5f8b46be8e7c7bafa02953e0f659a37cfc45aad2a53fecffffdf110aa693986d61a97a0543051fc572c1b4fbbc775bbbd01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d5e4353b2e0807eef0eaf9ef85a01051dd25a234cbdbc4ddea4b2ee35c62ab7fc7fea368b90633cca32213254d5387d52fc6e6d762d2869ebf0b8494b4e47a2251fc57931b4fbbc70d182c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000165b2823f87010dbc5827d85bf805677acf57940c8f447d790c8fbf1aa9a2244dd1a257e03a14622a582aebcc20b125bb2999513fbd407657f7613331ad60eec651fc592c1b4fbbc775242801000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023ecf5ff4f3f3c194f3d9eb09335870508220e806e8b431e838d8020cc195762332571889b3b47c54868e374c7f8ee63c7c623d0f8bd3a0f296c7b0e71132536751fc5a011b4fbbc7e0b25100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000293628b508cc0f839beec24bc2ac2184b52705a2e329be68719bc4ffe73c10dda1c4760410549996b0ceead7b0ebe4aae78121397c253e81349a113f443d4afa151fc5afc1b4fbbc7460b7100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029c27fdacaef6d3233d39854e89b89e0a63e9f71c8162142763343d8a3356f96e861d33b68d89987ac558d73f488b1709d50597212979759afdbdedd2e395b64951fc5cb01b4fbbc7364a4700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001da009207caf105f7d2f03eb994590daa485970f7cb429530290f7a11ecd3a595f4ca2a979ef40e33682387b7459ea763f6069516480ed6ade59ce9e14b24787a51fc5d271b4fbbc72e154b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e330c30d9501f512c79724efe93c56b430f2ee82fa0393345847c5f4be8f1f16ef63c8ed0e3b7fe68e9c3c4ffe95cde232b137d7bcc8f48ef9ef7924609c0db151fc5d0d1b4fbbc708810501000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ffbb1502ac9ac35e61e3e0e3c33c3e9947f6e7c8c33802ab6d5b570205bf675d70a43dec15ad10c02aa1ba9c1c271918c480d7ba958dbf23e40213e6e9be34a851fc5d8c1b4fbbc7ffcf5900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028d138ba806cf6421ead07eae5a0aec0daef1fa09d404f8dfe1aa25813f277076332a31f26ae72e5819ca25aea74be467462543e8983bf23b7bb19a83d8bb815651fc5df71b4fbbc7575c4900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022cad8bd84ba0d1660e6370980b7e7cf06fb455d7c44623dad5e313852ea74368e0a96422c181164d8c508a71b2e665b85bf047ca11cd4e0426dc897c875eff4151fc5e211b4fbbc7bf311b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001167a725f28cb8ef9554acea819692dacef2ae4d9781b2f3f63a73d3278d27a1bab0c54144c80d0c8a0f20459a1c65ec3852fa730eb92acded5cc20c9b55274b851fc5f141b4fbbc765e10c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001da0310231054670161858b1380a3eba9262d18e84828b250cb0c99c8b92c0d79e95483d0d425c5b30d1d95c759ae30fef8ce67ab6a3b796a50e8084f9b1a65cf51fc5ee41b4fbbc7033c4e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002450d64a3bc4a7d6325c79a34cb597ccc585fd4f72065ae6ddc9011d320d4fafc4334d4237904aa9267f4efb10ba6fed99e6384cfe78b2ff133cb43ac20a52c2051fc5f171b4fbbc729611f01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e56f335783d4a3de5e0b24eabad217318beab80959acbf25f3fc1d00c74fb5dccbf23ec04c2fbc96c93157db625219abc49388efab2fdf8c65206709d76fb0a451fc5f7e1b4fbbc711bbd801000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029cab4d56299b2aa0cfd7e090cf53aca1543752601ac67bb82d02a52a050b992a8c77bd946a0fb1fdc357a1d94c3018b38e32355e6ae91a44d574055b409f917c51fc601a1b4fbbc727694700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002462000d129ff39abfee9e99f305d6001b952dd40430f2b5065562e4a0dcb390fe1dda0512303dbf51f3a48fb0e8941cda79ca2bf783d63fb8c37799ee4c8c63651fc60f41b4fbbc7fec78e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001682329872e07772b169f808a873d12a9948b9a57833d4f577416dd7f95ead3f8080c575d66808feef2169de49d34a101c77a91208b0857d8ccfbad7842dfa5f851fc62021b4fbbc78baaff00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001136835e1f12ac20dbda0decc0a5778250e8b8678b8f01699fd9bb4619f7bb9a60a60c02b2b80b53d801043631f6e94cbc9efe98f9bb72b9fc2cd4ff8f6d5f85d51fc62c51b4fbbc71e0ae200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e225938cdd4b8e993d0c4d617e39b2ce2dba8b7b359e9c3628cf7a32a7e509c805f162320ba64ddd5851aee63920d732b74262267a96d5be0dcc7240831eef9851fc63111b4fbbc7ad846a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020156f2e7dbe0fde7b956c064343f2d9d9b9c41ea4d815255f994f30e1ba6a44557596b748f3eeba462a526a1ac52c36d4c861b9820bb6c72840dad91c4dbf50351fc635d1b4fbbc79fc62b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001292525e357babbabe19047fee5d81d6cd8552d494d78931a88381055af8a784784ab8bbf9ffe477cccfe301a298d208c905c63b263c7720bdb610748c5d1c42f51fc63ea1b4fbbc72c5dce00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029499b484d9e50e8faf052d9295ed9a72306661ff60419b8400ba8f816a001de9f420c79f82b99d1a9c66796b2ed31731ff886eb3236bc55e51fdf3f2fea69d4551fc643e1b4fbbc71c4baa00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000280dfef5e6dda4ca86c2f0cb28d7d25613337ae1b4ee735b3576993ba662c9245765385cda2812ccb9390cff4523e61e1117217335210e708076ee5fb9d2cb8dc51fc64d11b4fbbc776c60f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002949b9eb6e355b3a0ac047bba75e7f08e5361b3dfd316dc6304f9e3afa789c2dac8ac3de461fd3369a4e3574edcda4b871fd2a579eaa0d93a34341f85b3d62a6b51fc65cb1b4fbbc7c715e200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000288b6955e0657c18df86663c9c8f4d3bcf55f47919104a0ee078ebb9c8e7c5385a32cc436fa2260d12316b72832a73988a4f78765d234939e5565a6af7c11f22851fc66591b4fbbc71876a400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025ad72632266a32632fc6084337edccee95f243e0a85f0ab3e5a806c93eb76b25025cc7217850b15f21ef264439c52f6f1e7061330769762c93599678c9e825e551fc68cd1b4fbbc72a990000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002541f0e2210579f9d6a42a588f4e6159fa43bc57537b237cb53cb3028861336940b2117d35de281764959810631054fea13448d5e091ae51b3787c2b7aea5750f51fc687e1b4fbbc77e513f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016325fa008bd46c0504507341be99d49d00436934a658eecb8d0ea20044a6310fdbabb71045998460f59823719588b57f30df0ae12f56855756aa10c739cdeb7c51fc6b5a1b4fbbc7817ad500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000191771598cec5557f3fd4db6825574a90da50fd62c6af75a9aca41b158781878acccb9d8855d37388c2f6433b763e9bad428b7832a2d903cbf5a0586564b7d38b51fc6bb71b4fbbc70ae9be00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000292e8472a2e319ae6e6e82ef0562dde0087f0c6266ebd50f184ea931cc7b96dca4c6859080b5b56d54a6bc86a7e1d056712c3ac9cf14076a4ec340fd8a33adc3651fc6c7c1b4fbbc70867f000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001b99f1762adfde2877b607df75a8f625913a0a7fef8adb27b4fc3f40a83881d8e30e2b714c75db198fa6e0b6d2decd995e72fad7ba999232f08b8866059b6ed8a51fc6d381b4fbbc7bb4c0c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010412fe89f937649c7ed982942608bc90edce19ac2e49e9206e88933766c7535d13725aa62d586f0557d539e7707b39dceec0a7c5a8017cd1141b62c25bc2f20351fc6dd61b4fbbc7a2d06200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ac343fa9c446b8e7f93dfffa28ec94a961fb4a5127d7750c3f3a59600eef1edb4e943c85c851a2d253b81e8aa708acc4bce97208823b6267c2dea048b3c28afe51fc6dd21b4fbbc70e7c0b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027e4e246cf66939ae7dc22808fca0edb7d4a3622a27db9b28ae9cf499b063c1df9f9c2af1457121409a2d81409d1fccd04e1288ee8d58cab59cff0816c2389eb051fc6e3e1b4fbbc79f349a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ea0806765115ac1204a08d068eb95278cf51ba973173221c2ce538602afb14647addfb5dd9b9e5ac379316b3179807f3be0aafe42ccf665bca9778624c76217151fc6ed61b4fbbc732eb7e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f744f38d933f9769c39da78901489802cd67e2fee8a312db0f2636df418a8db646546a8c5957c406d1342e4c8a76a7767745c2e4b44e68389660a50c48c6470a51fc6f0a1b4fbbc7a7ad5900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002517f94ab656aece2380f368ffc45ded19a55f8f7b34fd7c05db2ff67d54ea86b7b41a4088ad475ac6437c45f2659813bb8b7d93cb6a8b84e390cd8454e1efe3e51fc71b21b4fbbc76a0b4f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a4d81a41151f8037ebcd9ecad78781694be36297a18bad95b6fb584320fe2fc5d3caac4f10cb19f63adf4ef03cdd3c28d7df17e92baee8b0d95458ad73976f4d51fc72091b4fbbc794843e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002df2106b86d1e70531e4dfd6c35edc103340fb7669d3b76e4ed7059fd537695117b31530a27db11ffea15926468675fa6f53adad99342b13d22b637399b7009cf51fc72c71b4fbbc7084a3e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028de2512884efe1559b1e2dbd7847dff8a7a16b8dc106842613c3d7139e98f80e30c6af35eee5defe56a385e792997e8ab250f4f85f60f0b71eddd759975f16f451fc72d51b4fbbc773d11901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002126b48d3665fae4586cc99664a13ddac8ea27c2d4f7529e36814106804b277c66b5c1d07b64d7f335c1ffadb5cae0a475bed245433eca8c448d145881337c49c51fc73421b4fbbc776cf9300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cb49896b583b2c3d7ba68924e10c99dad43d1be9425cf6dd053cb227ec184d664a82c7c8302bad10d92d3b2519a98ff4b81a8447c492f3c61362d0499ebcd4f651fc739c1b4fbbc7d6814000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017ee80b22abeaa19fc67308b9c06cfd582033620a75fe1beda7480775250b41866614918699c17384924a23bd2ed76978eb99130277b4b82c3ee5d405ae2466cc51fc764d1b4fbbc759040c01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001055e955336b81fb0bdfad6448d55e5b2c6ff439a4db4c150a7e244e2337d945c3800b50e8fb65bef7446fec9c19e7db96314c7af16fc94591aaab39f52d2a64651fc766e1b4fbbc7360f7d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eb1b4765402ddfa5db5793eac91f7d754987c3eb9a569d9a9b7a9be3c7d1577cb587989d2931cdc88155a30714766e61be055c4eb6a6b264f215f7ae6212d43151fc77291b4fbbc7779d2301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000287f9789a020bb5348d06ab7a74ff55918c1887e2e832f8b1a63994ad1104ff5d7221d782439273a18eb04ec4ec80f2b78391a5489950b8955d0db57bda61970651fc77161b4fbbc707190c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e91ae3b57de329feb30bac19c9e86489ffdd2afde033c559acbd2b2cee6b274500f7a3f4601e2ca556bd55c2dd840b85af2b8a692b2ff9d807be38a1d72ed33e51fc77691b4fbbc727372400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000293ffb5e4cb15df476b032ab08e28b33027e0cb66c19a055895bc3936368bcae078be73bd0bc951598b1df969b27cbe961ccefdaa42cb5d471996e3a409df627d51fc77941b4fbbc784360500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011a287da06b68feb541cd719566fb34f02f1dfdb1f0da0ff9cab20ccdfbc5cb79f4767e50c53eabf4039d63e86c6a72b27714c4089798253bd4a3c8611b1dd0eb51fc788d1b4fbbc79d094100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001185ce2ec22e08b64ac8ce40989972d3afd706c1963099828c4424a37610c58b3946dd7264ca344a5dfddc5a99e17fa5bd09f408d87c46e063fc2766c7a3cee5e51fc78981b4fbbc736970401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000160c855b6fbfa2819719d19e70f35dfbdc6425ae54fa11abc0cc017ce181a6d5d800c1aae07b73ba39cbaf6eb6663e394ae50acbfe7bb9ac5130a6518e0d9639c51fc78bb1b4fbbc73f164d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027db0a3c4014e28f10ebcc18b38d20705403872ea06f7d70b663aba98cddb6e33ee36b6c8234a4f010962118674891a53ed15673d4263bcb9473c15c701395e3151fc79a11b4fbbc702791f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020baf9de6709d8b1868a572d76a98c5c49d67d2bb0c6a879e6f300d0d9ea4262d471ced4507683a93341642786a1ac1d61f8a4d1b2a17e69f78b2d1e71b0f597551fc79c31b4fbbc75d74d400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016907ed03a06ba2007b0ff06f9645d47054d9ca3efbc6f4af78aae83086e405cabd336eb3a5d6e670138fb66ff327c40cc88c55c61faaa9de08384a4fab5ea39951fc7a9e1b4fbbc7e1fd3b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a372861a8ed097d2cf7d74c0feaecb6b207f93ffca22a5e6f95837a00a93b7b9a42df89ad1d4007a69ddae2d55605629a2fb3f8b5b70f01952698728fe8341a651fc7add1b4fbbc76b118300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b18d3a5d0c93f75019427eddcc0d10e1f7381c7b864b0bf000661c1ca913a9f4012bed383980c9b522685b870edd10cea7304a0127ceef6fe12c517dc422cb6751fc7b451b4fbbc7031a2b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d6ce25151ab4bc119949eaddb2fb85d6c30db49e1312f9e0a5434645d3c3833096212f704cf1a545c76feed6fbccecc335b88863a3ad7c45fac155cc75bae22151fc7ba51b4fbbc78deb4b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e083bab10938a8f7f8c5781e4630a309459b8cf389e7c5fb97b24ae4d96647690b78fdcc3a4156bb62842143ef7ed2b35b8ebad586f6c807c3b0884439ddc98151fc7ca61b4fbbc775374000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002507e1990cd47eaf4a318efa0c049095ff245f07d9a6979f82f9a811fd07062f2108d4a7b62565675488d581c9178f2bf00483d278f4b767af59bb98a7099aa7d51fc7cce1b4fbbc78e601b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000295c47a1bedd301a0e668520c0bc4801e548ba675e5e7acec5da5656872041374586e1007b25f47c4c86cdbdfdb88e3458a29177f3e305934fb27b02f0a136c0e51fc7e211b4fbbc7e7f15b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b7fb58ee4522295549c4ea9a1819278184a27837a090de39916c0a2d4a8b5a30a7c4a9e1cfbbaae214e02e835907d1ec001f35388d3b9ce9b71a8272c39e5ede51fc7e371b4fbbc7e47b8600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000240ad5f3b6800a881cb6e68b39f8e9f81531f9e268d19f02707be1ff7d4576b8f17ab82c5ab0c0915d4f70e8c33a062a35d557978962a8de8ed06e9c6baa094f851fc7f351b4fbbc70e0e8a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b802ad8efeb75f18b6efeab05c117d64447f666de8bc145f2eee71363129fa0fea584e297e90bb6cf6084943e20c8088d2d302e9978333b75b23b9cd3ea0197a51fc803c1b4fbbc792c10700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020d11cfba3b7fc62b1009e716e1444b8e30d61a07b4e55b8087bc648f6fede3bed41bc6c2f033dcc09c77daea641fca49e2f1ef764064cc94bc13d04b3f69f25151fc80e71b4fbbc7216d3400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e7238d7c57c5b1c9e188a1e071c5ef7a0b2e1a3576733c16c1c629399dd779a696c406a23c31faf0d0754afe397d3f74add1cb90b0ad9949cc8a83cab856d50b51fc81cd1b4fbbc78a6eec00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002756cfcbebe72754c931ed023af7d43aba9b2ac4df0ebfe8677170a39ddaaaf275c4227e672162fdb9795ef23857d5e0fcf9ddb5b25930510c7c6d1be6ef131b151fc82431b4fbbc73a779c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ffc508b9e27c6d20834ddf3b6a434c239a38e7ebe194ac934b6d3d701bb6a549d7c44a09e46a5d7d8e0b27a1b1bc61bb9dba51a2fc30b8d768165008216dc75e51fc82c51b4fbbc7deba0c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002644c97566674304b843267b096c567d15aa6e713e412ae9c6c640e0dd70d64c41a18acd13ab3256bf2e99f2851ffc8f6cbf53c120f24d827cff3178b68b5c2ba51fc83921b4fbbc7a3cd7b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e1a4f5902c298ffe8f9339d458af8d103affda74126365e95c91513d451b4f98fa92a6ffff692aa78ef7290a3f28544c7dfa522e36f50884b6cf81551f8f96b751fc83be1b4fbbc7a3922700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002638c9ced1d2842a4df47093938e52a8facbdf5060987ab66912fbaea58bf4e2f72ab9ee4d7425e958fdb75abd8a3e54e19f8ea9a32934c769262e033bef6896b51fc84051b4fbbc790d56200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002519c4a8601c520cc854dfb80f68dab32b0c8973fd836d87f1ecfd39f0534943aa22ac55e1f7d2dbfde05f866a5f16ad652d3dd6689752b80c69d7bb80e3ce14b51fc84961b4fbbc719ce0e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e727c12eb54705a8be739a214c80e6689e6cb2926ed854e0003ef5fc7af163cbb1f733d4236ce6052a1ea3098fa4ce969fde5896517971258928020f2cdef51f51fc849b1b4fbbc77037af00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000205a02ee21e4705b112542874e1e3eac43a524e954b2151296ec5c26e9b98424ca708c572281d0cbbcab3183701937943d98af9b0d3fc54f2e9c470db4ee6c67f51fc85ec1b4fbbc7d0471300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ea13c8dec79ff68741f79e4810e2a3d36ef23dc82101f03d9cad88a5505e4d02c51eb34e23e2afb07cfdf1a1dee46de61f1bda95a656f637c27133928091de3651fc86831b4fbbc7b615c000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020f873fcd7128d947f0c04e1c2064fd447f1a88cb47c1796e2433c2455606f9c81810ff35e0e9b7cfc161ff52507c11ee1637afd68926c20e793db125308b2ec951fc871c1b4fbbc7d6e7ac0a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a41de61b9007151bbbe8172cf4f1ddbba12a91233b0dcb18e3a4cc891dd571ccd90fd6610a68852c891bf67d6ed51a94cec90e6b02917948e5bc1c06cc8bb51851fc87441b4fbbc7956ca700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000280223323bb6bdc654f92d4d13862ca954d5460890bc0d272d7a662e5528a8d1d43eab544f549ecba88102934c6f34aecdabc79a66d9e862f088255cce343f6b651fc89471b4fbbc7cfd4e400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000235700ee16b8a4d3ff058fc448563f94e70c5ce0c57933c7aa6af1053c3b7bea2862cf971653ff68afb0e9f44b6f045bf057d44b682d0c57c5066a52636f1f83151fc89ec1b4fbbc7c5f49f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000200f7f31baa109fc73f9b413883aedecd280a0804af828f7e602518029ecd45afe93219c5f8c1e82b5526ddc419c57e595691fdea3fb6edad4dfcd59d9c0760a251fc8aec1b4fbbc7d6942600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000247ba26062a7ea79f8d52c9c97b99eb4dfb1da302ba2a908a82be0636d0942c1f0cd7be1529edcba349decd36dcfa65335a1d5a588051f4ff4001a904ed46398c51fc8b681b4fbbc788ca0500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002becf0c9d7e21b9c0bb550e633b6c66aca849ae7fd33a0f628a395c9ce91ef31691405ed0440c75e953a44b6911430c5b08c8978736a5abb507fcf9ece64d67b451fc8cb61b4fbbc717ff0100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000251ce7dd3bb6bf5c6caff59628a98ba362ffc075fdc9bbc59e6277a88bb82a4a142e20571db9332b71b11ace5ea74a6b44a33b83ebea8ca7aec29b811f692f0cd51fc8cd41b4fbbc74b79a700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001bc5b92dfa95da7e41f24b2c8472b4b79dcb13a996c11d91b47550d1e6e78a1ed87854a2dc9d3abcbbe80df02af04628024ca719199c5371505e637e12ccb849c51fc8fab1b4fbbc75dde7e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ee65d370208182a2aa2fcf280e7450a17e4fc60f4dab48261eedb5a3545da06aaa99eb907d25c489dee211b401697104a31fe7185508ea18e106418456546bdf51fc904b1b4fbbc72fb6c000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012c6b13fdab522f87569ad7795e0dc28df656e513d31e988dd19ec4bd5687ec8bed0ff61f6192fbb4118f81894d90342da4cbfc60d258a06c4b6bdc376aed92fa51fc904d1b4fbbc734572700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cfc41dbfa8de9aae7792e5ee2d7bb98d0b79e90efd45079c6634f56cf3b3ab916559e76b7bd698b2c72011aad38c6af696c5f80f98cd6977e95f5593984e87cf51fc90f61b4fbbc7b6f41500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021a31b4316d8fa14e0ee20fae775758b52eb661d43a4911f0db7310f3c20eaac4a58022b98d50974bb88b91b1ca4ee6798a225f816d5825ecd3c3390f04cc21f351fc91ec1b4fbbc7906fee00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000269e76c0c4eb0c9663a205fdd44399f6b4a238044cbc13716dcbe56e08d17eb86296aa9c21dcf2d8e6f5cb2ee4926757d83d9be30079de96f05bf9939e460fe0d51fc92011b4fbbc7698c5400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001eca525a85af98d93157bd41cef5e479f125f53574f02ca33ae30c2dfc957c17cbd63a17775c323cdb0f4856e92c94e0accb01c57c12a58045579ea6a7aac323751fc92961b4fbbc7a6840001000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015c7453897a56a17cf2191be64e0eb94721970971b34e0d2d3fa356986850e30a3c2c9d63c34fa44afd8d9b5209a5b4c2e32cc1844c51c69b0b75ef2b0864a7f651fc93df1b4fbbc723639f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027a42cb8944ac5f4d4c4a08d3d62d0f62fb18fd9251a923f2100661f4824e6e7ad114441edceb4668c5940791a5a08da43b9fa270a9675942d5923d6e42af3e1751fc95ec1b4fbbc7b4be0b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000266639a0c6c2f7120f4b8de1f2963cd4d946c7f4827609d8f70c8371c9ef18dceb4c809903a7c3fc2a857a9336fbc0e7d5c6f214cb3c58849a68fb64aa05dd5e751fc95a61b4fbbc7b1dcf700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a12188b7ba3a42fcb4fd2ee39250828fb1daa0b7b1800983245c33359f3eab998e537b78e097380807ba5cd378bea0998ab5be6c443b72d53a09c7f4f9b23d7251fc95a51b4fbbc7e7410100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010a00c8cca67ebd61a2a7e9ee83ce942ea6ae1396ff017dbf81c2fcd84b34ea9b052832468efabb1f0f0221cc49be870f04f94b496bcedbf4d3826875e5ff950251fc967c1b4fbbc7cb54c100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001da7919c9aa3bd71c57704ab9bd451770648151b123130723baec9f714afa3f15866c3e1a00b3d93cb41d637c96d9b524a65b4e2338bd85b780b360fd0a8db40351fc97731b4fbbc78a361200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000283a028991986fc9063f5c711a4870fac784556ffc96d2febb6733e259c77e3579e32c0f5303b612887c83529398ddcd0e1162ba9e6dcc0c8f63f2197ff23b19151fc97be1b4fbbc70340b200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000221166d72524b4df2be60237467fccb098345e826c8de6daa45f5c938607067893797f9ff5efd4fb5c114f6a85581ac55323f62c58fc5d711026896afb77a67d151fc974e1b4fbbc7a980df00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011b4b7e8af2261145beb1c08d5e1b9f54e0656efecdc40204d82f3feeb2f7f97691ce3654716f7022c39e1de66c25b1414990146072de55f9f219ec8d7480a35f51fc97e51b4fbbc772b5e901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026779df0fe76902b73655f00a7b3ec75491efc96aa5e38ec2ff613d9307656dc5267ee983ba21905966b6262fe7c2b559705e88dfae7c678f1aa408440945d44551fc985d1b4fbbc7e3e34c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ce25ffbf6c673ab9e53751a6c48126c19049b93eb068bfce6d89324bd302ecec7d60cd85291156f106a91ab361b6a2bc0cb1b73b3d8f10c815586dcd9765fe9651fc98de1b4fbbc7d29e3100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e62159983e555b97d03852baacf13673201d452acccb9cb2b822b07339cc76cd54eeb296580a466a438aa3561da752fe85d22fc79eaf4fca71fc85f7a9eb757151fc9a0d1b4fbbc71b6ba401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001eb200df1bcbc855209c57203bcbdb06138374ebdf9af1249fc5157473326f218d860bb22a02c3c59659d8786f51ac7416704499332489f94de3b0d18823fa0d351fc9b381b4fbbc795431a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000141f50fa90ab34ff65b09cb11200700edcd8f619a15ef6c20cbc6786d90d0dbccac915108cd0e01355777169ac84c1347c528bae20394acff777e33aa8f60967651fc9b4d1b4fbbc7ad710400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010394a7683d9e81e9e862d354f6c9c70bef2ad8e4c87c4dbbae9005a423d5751ea864add5d6747a3c991f2b687cef98114657a1c02c6f7beb21a8e6e0346e10c751fc9b8a1b4fbbc790b7b400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000177aed046c1a61ba27c5bddcbfda32df49b735cc01fc3e5a0b0ae44f6e13ffc1f1a0457b4a629c9a89cc7740b01c9d4b039b4d68dbcbc3b4e5549c6c6517bac3751fc9bb11b4fbbc7ba45c500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028d8f27c8db49583731fbb2aac4a0b86c4560289624c384d3773a3b49100c2b9f7fe1ba036601a365a6cbcd9e7d4010638219df7bd7434a907c7da1369ef6947151fc9c301b4fbbc7f4d22f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a550d723047d80a6effa871afa9560a59518addbd39429acb247e2dafcdbdbe7d46a0e5fbe86c3136ac4d942604e359aff0874ab78b355aeff9fb65ae6f416bb51fc9cdf1b4fbbc746e3a201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cbc3296d373471bcb0ebc45c10729e9ca0f416c80fb9b2da3886aaa7f0fd969205b10020bb76c00b8cb535127625f2c38fb9d7c405a5be6034f3d7edd86f6d9251fc9da21b4fbbc7ab3f7400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e551ad846ef5015e619f0c9d363e75ff5059b83056bf949c527584b1955abcd1cbca131ab89b9c9663a38753b320e1d87aa500bcf83a5bb20ce73f659a571b4a51fc9f121b4fbbc7fa800d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000181dbd4591f72f89f83c0151a5d10d4f9887da270df126b0b2140c06999623b092660a4ae9729fd303bd55b524ea533c640a0c8be74039348dbcb312a26f8bd8351fc9f731b4fbbc73e8e5b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ce6555e6762ced2850abef75c64c6ef5398ce076c28eae59434ec0d4e8c3be04bfbcee53749960190f0ee5facd1155839aa4be506b53675cac65f75e5eba77d951fc9f541b4fbbc711449b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fd1ce397d07f750556a3485558b9ea7d5b6d98b8d8c9f4d5ace7f5e344374647cb117ba19d089e31fea34d855dd71d622ead10556a9397c4429edcdc37f265c251fc9fde1b4fbbc7956eed00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027ae8e728cb97e00f7c478c34213eccd9c27e68d46efffb450464d246cf8a20c568bdc09317e3a1045879d07ef4cfc8f0ff5291889cda92e62d48861554fa76cd51fca04a1b4fbbc7b1774f01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000235dc27489d90c1bdca4cc7f96e3e4c1144675e0f4f317484d7be86789e02c42b35000b59b9708c4f5d553df19421c4d8a1c5781283077f92ab42b7f9ad66bc4351fca2141b4fbbc7f96e0700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000219e9a4d57553721d5fcba135587511361151d7680021820d2b4df9001bcc2c74705640fe92076d60f6de2dc959716408269baf69c1b73c1e5fa6d5ade2fcebf951fca2e11b4fbbc711012500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002da79a1c24fd0f52b9a36769e59d830467c06215272c7c8a538be124106565ed094d4927afdd66d13799cd5a8fc4ccc57845130dec24360ca46f7ef1d0294003151fca3241b4fbbc73fa00600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025e1d5b35f45cae1f7e7730210dd069f5935503a831d91c0465df861e32e87f31ef5c5b7e85ca768ffa8575eaab5f2b39df185b5d5265c1863c905eee2ea407ef51fca3aa1b4fbbc793e8cc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ee19b2823f9f3e408ccc55ed951eff22c9e476de5042ab8d2b9161c89081e42c0edae9f72d1dc213dde5d4253264c3cb5b87a2ce74dbec2b45bc1c784ce5ac2951fca5c81b4fbbc75d41ed00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000289d3a86485773733e814102742db9340b860d13e3593895792f25cbef2b6e594d7c41e4bd30f288718220bdb65fa6aab0c092fe7dbd9ce62701521c2f97091a651fca76e1b4fbbc7728a7200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000217c3feb32a5ae001cb0c1395faf06f2605dd1ef28ac4b527deccb463b2d13d7c87c9680498d24fead17130b8d438929994a01b19434cdd27e69f524c919d6b2d51fca7a91b4fbbc710c13200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021cd9d371c0ef7b06ac9f3d69f4e4b150cec27440dfaf20e0ca8190ee197b2dbf691f8fe9b46f7cf0c771830096f71ee4061219cb3d5ea726d595030cfdf551b951fca8571b4fbbc7c0991800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000161412dbe84aedeb75dcf9db47d1f080abe534714febb380b263735a644c9c6841d765a4bb5aa4254b2108ce66634abf6a0c750cebfec70cf47374c9b067c132e51fcaa4a1b4fbbc751c6f401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bfd64cd65c46261329ba4b14a72e001358b07fefc0aabf4981077fef0209b6d01feb27dc6723d2013852380fa8687d0c27fc03100517ba81533c540e433a503f51fcab221b4fbbc779cd1f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000255c3ef37c135f5cdcdb161709d7a791dfaa1e1a6f496a62952950c10a2c0a1940c04b56829e4e91bb5ffd4191d37c411a44fbfd10dfe7db9d65963237af2786d51fcab3f1b4fbbc7f8c94401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027f66fb01b77f0e9144daa0723cdbc85f41de3621095c9cd52b6c28e349b4e33ffa8672292bbc071013f72b52c8d673d57b5adb0ba476a938760978e063aca54c51fcacfc1b4fbbc7e0e47a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010879e84c532159330d9e40cc35fda2cae96f9d9143b0e0f8b96921776a6bfb7e1e7df3f4aaf0e7d420c8458491b7ec2504179f7a0db0de96b576588d2060ccea51fcad431b4fbbc7ba4bd400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001eb55e63b2410d32d48c80ff46520c2372e402c15cb8bd28d2e0e8768740bf4119d3c8d0570ca107d2e39059c78bcf7320a9fbb56ee0f82b91479f927e1c690a651fcae1a1b4fbbc7c3adda00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a052ae827080befb7ea4c7ad8b4f307bbbab6bdbbbf6bf86689d004198b94684959f051b96bd63d0460ef32e47645f1d3f363273b6b57f3267d83b0b004d311e51fcade51b4fbbc797822500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012bb8a93109061d2664e225636eff993a53df921558e6f471b492e07745d1e6d71fa20207115d18d9d4df5388cebd37249ce2337e965a288b7cfbfe5c9106130251fcae631b4fbbc7663ca100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001377181a3e7e9a5304f9edaae4e778f2b7093b55b50c09b3e9e2c058da97db24b122d1725d4be2ae23995f492bd7a06b735770f0b37b89747ca1aa514f536e96b51fcae9d1b4fbbc742e80100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024fc81f38459f98af3c268bb3709c8595a07045ad566f4e8f29e740619363aae6815fa543f5deb97c887c8d11987b35a0cb1060e117b6b43a43b3a5adead2d6e051fcaedd1b4fbbc788451f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022ca85f51840e289d9382185076838f6f5f264c0bafe6618f64a0e1c2be8b31c7a966a8a47512ccecb8393141477ad4ec4db61b568aaae800dfc0767dfa688ab751fcb02d1b4fbbc78d538401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bb97f6d1c0243e525c36cb0b6a3bfb76356b6845e543c9a27f8dd0c2a3f0d41176da2903e59cb29df9af25b484275f83e90664820f12ba0d9b092ebf0bcd149851fcb05b1b4fbbc764d27500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023b1a1b1f4cbd5975896798372bcee4e5e8b03cdef0e4cc1d0cfd8eb1122ee4cbb42c48c2e0c0c55a90d2c72dfebe882938b0f4038301f76e4aa7f2e719fc3e3051fcb16d1b4fbbc7261de100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001b77b84293869b3638c893c78f2329167c4f1d6f8af19e4ff2df8caa4dc450ef0e2c1886b05da9f1ea26c283fa3d357baa5827be62e2f5f8ca220a4334f48f93951fcb2ff1b4fbbc7f6e90000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002756f4e98641ffb92573efb1885eedbc40fbe80eecb5164e3a47bb1354c030f1e9c04c5fe9f65e4158e199236e3587cf1c7f6df8bf26b7675e44afb806b6b021951fcb33b1b4fbbc76f211701000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002094de5a0512a04767295d98047dd6d999e41c0a4177f35df705a9176d04580d72a3341c2ecddcd1b8773c2b6c2e5c2bb659bbd158837bd5c28b086851243496e51fcb4371b4fbbc7c5e28200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000194317ca748953fa2da2bcc5d95098d8c6bb3fcc8b0fb71e73ff9cbffacee98f6442de0718397decfdb22480fc33c028abeda58e80dc872c37e47ad71e87935f351fcb45d1b4fbbc7fa072200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012ebdd162bbd48462b56533cdd9b8de5da48e0b8db636ddd9fb3b1a8070fc0a43bc04c0d16baf35f1c6105e5ff11fd57225c4c02398799c5666cac218f664a31951fcb4901b4fbbc7bb4a0d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010538e322583324d274de98897fe92652a04214f6fa6e3f8737ca836fda188e207bdf72726db201b70501cd568549022efd0509555aa6a7392749f27e598432e251fcb4941b4fbbc72dfb6900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023bfd09aca44d88955c3634f8c42598e3ebff2800d629fb9fea7427ce254addb9562a33e257bf905e26520c3bd8042d4199b1ad4250d4423d1d9e87df44fb797b51fcb55d1b4fbbc7bb3e5200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013911a66bbc9c59615565f73a18d70c002ad5cb8cf9d0ea3fdd3b56748ba93ab1b85adaf9a216d51ada714349b1252fa34a77c06aa1a1217fdb4036242bdb04bf51fcb66c1b4fbbc7b47e2700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021b2c33a4453918bfdccc9969b3084c349f9d84faee4c22ec98fe4a3b5cc7998b6506ca3ff81c37a0611f1bb7457e88f03f787b02db0d0a7a26c58160341b544c51fcb6b81b4fbbc7ad974200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023c8468c54fab6122206a4647966103e3e3025b3a79b140a5aa643cae6dcfe974fb535f74ea01c399ac3e41b887276a9c534705ed805151b13c489a67536a66a551fcb7001b4fbbc762bdb000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f441636957eba8cca1d97f79f9e67b0db5e75304953e75062da3e9535017a5da18fd8b941b2498e22c0549dca5137de09695e8dc1eb70dd2301d1544e27ac06051fcb7351b4fbbc7deb13301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012968095c61cf8d023c94686571aa691ee886caa2042c004d0c5c7677ec22a2452f513fbec172be3ca939258245f25e24488ad12f0d8b0aebfd1d2371dcc4242f51fcb7e01b4fbbc77f250c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c4a5454be7385e5066a8e698148eca120a2ac61e9e67d3df6a84ce75b44908133936cf1d68860364c06bca1225f1dc9d8ed8a2e7a0a1aa12eda6812fb949e04951fcb7e71b4fbbc763ad3300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d278da3ddba684fb813c6ecf881ea01484e4591c01ad589a8173ec1eb49f486a5cfa37819bb8802b60b3b065ddcc3d6901e1e135414ccdc54dbf2fa64b2c83d951fcb87f1b4fbbc7dea11a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002120b578831341f2a33ee966cf690ad9799afdfddf43903382a1403a61bbe249d1b5cbab689eedb0d58edf03bbe415b623a6c95d3c8b84dc6eda45b83d85004cd51fcb9511b4fbbc7ab680b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001395f429e1ec7603e7a9535768eaf27cf0fe953bf459433f69f2667fac8e2200508bcc9397c8dd718d0823f303f7e9e401c9a8376954336e767e277987dcbaab151fcb9a81b4fbbc738fc3500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029e518ae36fe75140e858f3749ed337f42df1aba0306770b9435bdcb56acfcb502ff467be0f35b2a4e0da65936cd071348627fee539e675796927884da9e50eca51fcb9f21b4fbbc7dca98100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000249503740fc56221899f2751798525ed5983311fb5e3bffb7d3371841fbc7fc5fa20632e05d6c95f51c4207c079ff1d00dc74785721c94aa73d71e5ef1a51b08251fcba381b4fbbc7884a1f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026f4dd12cde843fa6ac99e60469bbef1e8a787de0245b4066d595b016f7073e1ba4fb79842c0daf2c49a090248c0748eca85af9cd99a1944ba32d1a346910704a51fcbae51b4fbbc718126b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001700d6d951cfd179e5f339114abca7cf1dbdea599a114dc32c088a0bf318e9921c2a69c9dc2522f16f4c69bacaf0e44b6de1fe509d4e747328d780e233c6caddd51fcbb3e1b4fbbc73651ce01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fa8493441a91b05b6e5f91d006668b1802364b47b2b7bc5e564d2ae900298a571526d66d3ef2e5ddce6bddde920f4905c1312213e9de880acf2f5070efd020e851fcbb721b4fbbc71f0b0e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a4057bab7f50871d72f5c7a441cf8fd473bb471c290ff193624809055ddee9a7729b1f10aac92f90a575431b82a0f498871a5a258c84f87f32458c9a440b59d351fcbcc31b4fbbc7f9b93900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a1fbd5d6ce084424f5bee4446f06bcc703a88adb151c48c55bf363b2b745cac54b50241dfe308bd1a2778b7050608d714809d4fa47d7e8d1391834dfa8bdcad351fcbc8d1b4fbbc7fcf36a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025c3c0c5cb1d3a10713ba17eaf1cfe875f15b1ba9a536cf4ab1cc39999254f18f166d2ee7da3c64f49941dcf9aa526a22a845a28f0fb10c1e1d75f70a5c8d352451fcbd3a1b4fbbc7c9b24a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000138893baf9ad633979b90befba7fba55d220bd0f9fbb81c822620b5b68f22209268fbd4d6ffa94b99004458257443be3dfd1393d0762f4d5406583a4270a6144c51fcbd461b4fbbc7b8b85100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023d27328ffdf444ef7a36eb6ff151dae4cd08828abf134454bcb30d065789cc668c2c83ecba6627274236c712fda3c4173ca9e1c171e271bd678ef308491a8b6f51fcbed91b4fbbc7d82f8b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000189bac62bb1ab460713d849d42fdd3a049172dd7afd5123c7d5f20a7df334b9a602bf0db1a36bfb6802f1bcd7529a0392513edeae944ccdc44d5ee4840d1f28a551fcbeef1b4fbbc70d010100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002457674ba5525a7734ce9bef4ab0c789165df9172e6b1a9146dac0f72ed405adb83979b7df037975fd0bd2c2671d95fee0b17907afe4a760092017c164b47e94a51fcbfd81b4fbbc7f52c9300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001694b2f296e22e2bf002b9005765d54c298d3c5fc23248bd6793244cec0e0957dd282f36dcea2a33f9c6bc2c5401421c1c6ce93357eff642fbaf31b0bf2b98cb751fcc0271b4fbbc765e31700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011f72202b5acf9b61d5b6464761265a4eeecde35486278012e5c29d6d316eca067afa5c03d70d5f894045c01e79f47950a2dc53f05ef99abc176d1575416c4ea051fcc0371b4fbbc7ad477c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002572a650e809e438a61f4657dbaaac41e594347797318f1f5b0301b0bd4e9e26f36af675449ee23402f0cb0cb9dc8f9ca6f67d13b5847c248deb9ca0bdd06a6bb51fcc0d61b4fbbc708857d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cb60031ae6ea349dfa90b17399e4eecd2f10a760ee7829b26c467b3d8ddd18db1178dafccabcee74437168dbf1de015e855fdba9976a4a61504eb71673275bc951fcc0fd1b4fbbc71a929800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c912b22e17fb9b4b84e8e110a0731fc569b0e561280a6b32d1a46ce5e016791104779162ac49ad13ca3b74bc73f4545db19b32547d4bf4517b747afcf2130e2a51fcc1931b4fbbc74cc79a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026e8be6336e00a30cd978f4db661783d8d83029ffc89a8095bf8572508bbebed4ce854a7bbc02a45ad60896f57c9af36a3a5af3d4a008c5f06136f08739f5ca6551fcc2831b4fbbc70795a800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a9fd8aa374d1bc3fe7be1f9d20dd2fb92cdef4817b546c90bd2d7e72eea46418ccb4be94e0d7f74f08dec00d64a8fd599b470658bc507a563fb02fd56102ac5051fcc3491b4fbbc76c472100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029e741576242fc8c9819083717d619bd4edccdcdfd2b8b1ec14130e118458768d76b4876ae75afc141d15f657a9fd616d420fc8c8c3114b776115ffb98264617051fcc4191b4fbbc745d26b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001af21b6f214b47bd5c04669f8ef15abb27969846e039c28f7f4a4a81a20e503150b8435ed13e0976f7680eb3b40418290403c10b5ede98f63b00e6681f8089bea51fcc62a1b4fbbc792d5b600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f5ba7bb3d862a7ca2145c36c8b84742f3e31e703cf2c67b9b4b2b595a26f9a072e57213106b5d33359ea06c473246dbfaa94bf2a7775547ea78b7c67d593971b51fcc6891b4fbbc75ef11702000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020f9d77e5c2a7d347cc771d93372b3d959e3ef0a863481e7e5888d991bbc122b0358a632b28a96b23aed181731bacb99cd634ab01045f29c921bae7b54ae38c1151fcc9e11b4fbbc722940000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002de23fbd9f84aab4797ce957012eab56b7321f0ebb88fcec2350c44698ab6ac274eb6642c27c4a28be9160250c086238fb2b07b55a6c43fda0a4d9ad868ca6b7a51fccabd1b4fbbc7f5227b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000261218e5613e7dd472152a9e3e8dedb1022c55a2184c5c555db03e8f6098aacb9b89cd9959d523851f3b0c874b66b97071d451f16af27c66dfd3f9a38978e373051fccc5e1b4fbbc7fba69700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011be61e4f95bb13299adc9cae3f5ce9a376db25ef4a273c6e28e60a109acda63bb491dca6ff8e88f0f7597f7592ef1aefa3830c0284b21cf9e4fa50af90eec2de51fccd091b4fbbc7cb6c3b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022201d622712c14b48e97499df80e98a4017f5f51f7b722956496391acfd182d540927a7caf82bb76a90b72a1885029b7c5439a19766a6b7ff0c72ca88ba4335551fccce11b4fbbc748893b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002646e84d88c1f0358bfb213547f5f93078940f5308bd1b0b5f5ce07efc06841df62880e941ba722c1a261e6079b14a57c68f172edeaaa92b501e27913348acbd851fccd3b1b4fbbc7dd286300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e10e180b4c2fe83b69ad0a055a3b8c738ea32687aa613b0c92c08978e60130f1bebcd946d3c457b4d7ce0ccd78354a4307798289bbe289ece06288c9711bddeb51fccdc51b4fbbc72f1d0401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000112ecb555b7600d3063621fa7c015a7e1b1931e409f71d08320bf0d98f17049ac2eae6b39c5a78879d1694e7c80fee748de046b3ee34a6134dffa098fad41615251fccea11b4fbbc7f18a3600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024297f28a7bd4118e0f056b7b12d1632489478c0ff7c9b525cbb8f248764d567f83c0421bc737768d7b5d059ed3aa9fdaefeebe9ffa41394a20170f226c419a7251fcceda1b4fbbc7fa372300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013a3ca9f1b0bda4beee1e85ae6421754c3543d626eeb7580a3da280fc6f8a6f714d58c6ba4bdf26a385e8f00484345c97f51addae18097c55bafb363d92232c1e51fcd0d41b4fbbc7c4884400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000157cc2b1cad0b3227e54469992f858c9b37e9f84b0eae8b28e166695f68ec07a88e13768adf054a2c3e20a3921c6eed1f777c69e8dc0b0569d4516550af52acd451fcd0df1b4fbbc719eba100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ca39129141026ab4e56a99ecc713ecee4cd45ce345d595c6adc7ee983daef5ec4181189c0ac540d9a88b4e13f5b3597c8f0306ef153e7ce26bd65354e08341dc51fcd3c31b4fbbc7c57e9f01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012fcf704ee756ea944a1e52df5639b2c7662a40e99881c08f8fa931d37fcd05a62cff795c923f61174394f3fb89db54a512bad74461383a1101688778968d110651fcd3da1b4fbbc712c70701000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000251c962d5d8bfa43cf74dee502595ce25d72b36cd9eae92b6e84dfd9ccab053db52976f02d97c43916c0602c3560dc76250600a8a7dd01fdfc865c0364bccb2e251fcd4aa1b4fbbc742285800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002aa11a2c9a9cfa8990591da20a62ea2bfd819e354a6df2ed495389d7a338159201fd25867d54e902bb5818b44795f77563da2a7f7a2941f9386c66e0835efc57b51fcd5e51b4fbbc7edb73300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025fbc1c85c289928457ec86c01776020e773f422188e619647af4eda0f7d7633f5e63647051e8112fe5a7cc3a196aadd94c596533f4c2ef28c7809204471015d751fcd7b21b4fbbc7a5a75500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029990db9572ee3d1bb8e9c16b586f40e611aa02b92a488550f921e8fc73192edc5453dc95cd89f8d8c1dc47ffd15d67699582c406577d2c89afda606f18073ec151fcd86b1b4fbbc77f380a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024f706ada73d7130f89f148f3dacd761922868858f9d34250c597602756f48e3d4e3f1ddfc950eaaa9e147beb1224041e3e95e0718d0c0a2017e2339046a0227a51fcd8751b4fbbc7e5eec300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000223d1ad89e7e8d323d4acd5c79a61d9c8b6ca18925f3ef5c8e748d6d81a4179c799254af020135fef65493935bd66953f09a0bec595d3dda5e67ced5f165baf3551fcd8881b4fbbc71fa72601000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001977f5a3de6453dec594b78723b2f74fcd12356223bef5dc3bc035f9fd92f6f553c4dcf5ffbaf8db8adcad8b07a5418f80e83b5eb0c8e44a557d720160141522651fcd8c01b4fbbc792f03800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021dd94dfea8c82b0c7a5a6f70b9b705881ae9f6efcce33147f3ffff8b178cffc3109ff1b6703edd1d3870c63be9135ca09d29774a185519397dee9cd007945ce451fcd8cf1b4fbbc77fad0500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001eed3599d9dde49cc01dee2759f0e4db9e47831c6592d92273632f927cb9ed2fe6788e0d51b056c2b3f9d62897947709d879c9935241894cd503eab8e4e2b516951fcd9111b4fbbc7303b8001000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025c314ba1e975bce875dea75539fa666f55e5cc413f09088470d212944796377f1b47f1b683480b92b8084505825cdb98a932b67cb12fb41fd9dbf7cd69cf673e51fcd9d01b4fbbc737557d01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016ed9398b52f0518dfa08bf0fc0e19cb8aa9d1f8cca7ce5bf8b83e28f95da02ef95adacb1280347c9310f69aff0e29a7b0eac525319b19cda9e6b123f2bd66d2851fcda041b4fbbc73f694e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001615c05f99364910225a56ecabbc205e5665a844933c9ee30fe43bcb759c421bd0d65fe3ddbcd1a1ae2219b60a5b63fb5dd5a55481cd496cf1b8bd808f0a46a2251fcda8e1b4fbbc7e87c5901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d20b6f93200160a6b52b1ee5a00e13693f0755ab0918a3261b00a177345bc7db220517db06fda5df7d8d2f358f094e045022b5497cdb92d550999400761dd17151fcdc761b4fbbc756645300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e9a8235307ae9c911cf9065f0dc9e47529a9cedfc0160f5fe14a5e32ce61a9a59cf9965ad95e5ace8b46ba354e1dd50f84f7293aed011c820e1d6679cc31b4eb51fcdca71b4fbbc726061c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022ea12d442b623ca2472428512538213224f6c51e32ee779fdc24435d1e3c0f19c037fe562412efc4751b75515f91b2fcf527c69e772430a0d04f04c72c9e788851fcdd211b4fbbc733d02e01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eaeef4dfa0ef2114e9addbd64c79619f712e8ddb4716d7b344e026ec47d56a7f53cfea354fd7507eea357cfec7604d9a2ec4ee4e8431f9e47e8c1154492a07ca51fcdd0e1b4fbbc791fe8700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000220cbaa9de5519fddf3f95f375878f20a7b590612291421384f0b3fcb7e03ff19e43c12e2e1f23457490d835c3fafca8267d8feaed7507273d02c60c827242ed951fcdda21b4fbbc722820c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024c7379d2b291ad3f0489aa8a8f5f3a4367344a651fb9e0947f07b5fbcaeedf3de78c1c9f27903f3cfe8754785b9f4c5efb8ad5401d95a1aa93eb9c1743ed876751fce0561b4fbbc728382d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015ea10961e32b91fed7a09d8df4c5be71e26df1f7bf236dbbd8f214fa28bab3211f2f4210307a056148bc073df5cc1f16ce2bbdb790ace6647f708c96db6c307851fce0a01b4fbbc754617300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000245490633ce907747fa202b303983238b550dfdcffc0ac06da5edc27c6eae06b6aafb93e2dbc0fa382584e5e40bd5fbfab274a5887a3bda110dd6a667d51aee5351fce0e71b4fbbc765501300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001aecd70a064149ff607f6821017543d1d828266f05a7cbab31179e6aee7fa4b5f071cd770a87baf2780a998d977e440093dff54cd31030fb9afcb6669894efc0a51fce1a81b4fbbc7f1228d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e3a8a7bf19b93e6692c562888562db409a4f7b757c057310195f9fe4e9380650fd72f221cc544608a10b7a7a1abf331f0928d09db1bbb5cc7e090aea167d155a51fce21a1b4fbbc7066a0002000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028796bc88733e089d093ceea8866e814c65d2d63efa1e38c2059eaf8310f189fe5c63ca096f17775539586be874fb753718d293050987f075165937c2f867a3dd51fce2b91b4fbbc7c36f3a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025e085976cf64bc49f1a2b11c5277a7e93844b38c719638f4ec2ac48c37b9f39f153e61622efd965406496f745476306d3d128aa6902d3d9a8bafd636ba562d8c51fce2cc1b4fbbc7e2fe1c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028e261cbe4342feab6a10fd635cae1a0640fdaa1c1744b6c9ad8ff31efb896794d86a3306f51022a59317baa276dc9305e68314e059d9c572a294e689cbb219e951fce35e1b4fbbc7adff7700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f4cedc4af376e3a50448a93633a9a34e332360f8cb25d2b834e9ff8d83baf6b9b67a25457f930974a78c33c5a6bce11e361d37c4fa1f95759fddf2deecc2e27b51fce5411b4fbbc7d797bd00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c437d26ceb1c186bee55e444c28192079015d0927d65f359b78d4d3b6e4a733230def4dadecec0a9cd38f775bfa33bcf0124f2a10b4a4bf44a0aa65d1cc72fae51fce6161b4fbbc760f0c700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fec2f7430d1f8d5fe137dd05ef0d7477d33fa3d469dcadb5cb6774dda1b2088562bcacad0fa35110db9805e538c5bdb1779d80755f1e9399f2185cce7e10868e51fce6b61b4fbbc779954b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027d782f3a4c5f3e686fc774d18a68a65a654b6b229eef50c4daf3ad177d1534763b359b1b3396bec3fcb5a67cfbf44ef35f556bbde8b8aeebd1f631f446c8dea451fce69c1b4fbbc72525d600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a383f8e5eb16e38098df3103fd5671d2e6bb11c9081321ba7fe38ba970423656d34645b174c9f61e369996e3257c56e9dcd3698aa54d3ec29b5364b4b912421f51fce6b21b4fbbc71e026f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ae1e954c72751f6b3e5f5d477b67c95560d5bd8a42ca14b0115200038f8983a8652a418b517f1390f7f2d7f25942af430bdffb8252ce85216ffb6b60fb98b2b051fce8c81b4fbbc7902f2600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000160448b42c8dcb9af9d7e72316b53ed971a24b1bff2b886f03faada5ca19efb46c77b3be231de3d079e07e3124286bb7f21821590f6b5d6615d0b3b477121341551fce91d1b4fbbc76e721f02000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020990832fefa28f4bbe717dd19eba4586a542d91c3393170efd7a49fc69fd20ecc80a87c9ad745ead7d60e6d3bb525093da44acaa824014d022151cd71dd95fd151fce9091b4fbbc7c5ae1400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c6f58e8bbb60025a30bc248601d5e6f61ec75750e5529aa9ea3414e0069064e182342b7e2047aa393e91901c4d79fcfdc3547cfeedb380c51c86fbaf5c0f1d3251fce9731b4fbbc7052bb301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021b992362f990b7e3457360023d8fc39b1b64941dfbe1ba4f31c6b941a9aedd2905d03fb4d89ed238d5b02b5d6e119aa3a8c6e83a5b75ce11ab705023693adf1851fce9f71b4fbbc7826c1201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c105f358db8d7139e952a5df76737f2ed66f1da6d9e767dc918cada6b078a12936d0dd2bf7c1985edb4e5738c779c49fcccef1756af882fb9f0d2fe39fab80cf51fcea301b4fbbc7b9f3a301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000160ba0bd4069259a28e031142c4f857a419ea3f557c5f802ab3543d56b8c8fefa6a0f2e5e510a93caabefd77f3a4f429c5fa31d5b58540db676bd79f0c413b94451fcea6c1b4fbbc7b7940b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cab69981b18eb7af7df41f21c50ec98cb899d4cc9a84613917a3b935ef878f2a39e377b702844177dcbedba54ad05ebb19552d4824a43bddd94a7631aa9bb79d51fcea941b4fbbc7a5e96f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001b85d8b2c9db7c883892e87196d8e766ff9da510980b45778ff79434627fe8e37e113b4b0ee16604e7591908c9639744bea7def1e96e03bfa72a51ba7c42ab54551fceb911b4fbbc77d793600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ef982c3a89695936ceedaca8d59131659c802459836089fbd9f4037fa637085ebf2ab0f6801600f2f4d7aac293e6565625617b516f8c16c216f61ce3e0a2bd0251fcecdb1b4fbbc7f54e4801000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002af989fb7209430ef8e76d95697a998917d06656d311624b2ddf02de62badf40c6d877c6ac14aca492f3fad8ea450f4042c7eaa67af2cf9ec57fa74a58044228651fcee8f1b4fbbc75dfb4300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010f40c59781d2d1a7dd87e4669f0ddd0f369b765906a4848156c5388bd671e3fb79f343c630e22a4d302712e4cd468f0d2fa12614526993af01c2cfd82aa4d0b351fcef211b4fbbc7bfc55c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029692042365651b2a9766d10f149d5cf4be048733c2e41cf804cb7f91144e8e79d3bcab6378da820649e82ec244f55aa0f1561404999376dafc79cdc8d0c8c56e51fcef371b4fbbc76ba83b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029485c95b24742088eddbf90c4ca6978a1837225695cb209fe0413e4d8d83aba3b494cd97e93f98731de017cc13c1de938b921d9069bba12d4eb9d470138846fb51fcef651b4fbbc77b285f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002dddbe3aef050efdb57bde94d00463fd35644a4b88ae26118a2a3390e97d686a5da2074e7f756afe3ed4df84bd2d621ed5286165c9c6155da5523812f6b15a1a051fcefc71b4fbbc74c289d01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d8acd1d385da17c3492c3206371bc6b423f9ebd69bc3577652c6ff971c8531d8c62b2ff16a6f971a7b9789e85167c738804dc8ba0a6ca8bf733153d585ae6c9951fcf0111b4fbbc774a5b001000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c9439f9a0ac4e66409f9dc9c4a60f915daaaf6a0dded0546d267b064d9652be59445294a94094722b1e7e67d0212d2edf40c5f97392509e877857a332f7efad451fcf0561b4fbbc772033600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000163e606c19fc1a2df4528ae6c657333763dd7ec612cb5764a1afded0837a326c03d6fe3255286c9efd99bfac6d6231e692f8ccb8a5d4215a3af8b552dee72c5c051fcf0951b4fbbc7dd2b3300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b5ee5cac3dbb5638677b017c4dd6d174e31ce550600eae3a2e86d7e149ba0bb16cd4ee197ce6002a5638236ae60649d699e6b126762f3209525b908ed0c115cc51fcf10d1b4fbbc7febd0700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f361213b42c4ce7074d83d257f00786351b410b9d80fc8f04ddd7cd1a04bb7075c655cf598228665c10238698dec09c7524bbd5c1c8f143407403d3f64f7697a51fcf12f1b4fbbc74f65d300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029cc74861da6f5d173a8418d890aff73321a6ac12c37aad06d64edc0ebb63a66d3b6a73047701a70f8b2752c714e93057763ef3ec021fec180cbfb5f654c1789851fcf2371b4fbbc710c2b300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001cd2ed9b69e9c7353fa9358d6e56c06299e33961e1da67423890973142762a713d42599be81961d694e820161e8e857682b5e94214b03bdebfabc3b6e523ff6a751fcf30b1b4fbbc7e7f72300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021464776a25515b9d63168f2416aeed49260d8c83478a86a60d3a4095d178846659aa0b0027c41fa5a4640115738518c4d238f58aa2fc7f6a45e7e02ba704f37f51fcf35e1b4fbbc7312d5800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a8b9d636ac7bcce5e70432288bdc904f4be99e4aaa8707c90950b8dc6181740388e176bd2ac1697781410d25b9b702605f1f99a5b7b87f7354f6d83f959ddf8a51fcf4b41b4fbbc7cca41500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025efbd894b0895d89da1d5f924abba507c01e45bf1419795bac8cd6f1a377d3a946025ecb4e1e6e26c970c019151ab22f45193cf8b566313fc9b2d19fd22ea82b51fcf5f41b4fbbc739a02900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024aaecb4c2b2baee08ea98e3e4a96f4a3e3c8d624b5506565951177cebd5001920b2950427e14dab0163d4541dabd270544a86ea2452414a5739861c62028ec9c51fcf62d1b4fbbc731b62300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024965f2f37742cf97636f9c34f71db02f865ea30485e3c3120432d8ac454b8fb9fff54822975cf6dede0a23b60f3643e17cfa06e1611278ffa5fb008b221fb05a51fcf78c1b4fbbc73e2e4101000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000244f6057d514b7479f4a1ff68c8ca0c1be7d4c3ba162b9a0648dcf10a44e267a74fb401ab69b64c2509cddd11e8a95c4032a4e9e75f0d9c7479b9a9a0167f885f51fcfa391b4fbbc7ed3e0200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b0477acfa875a10fbfdd295168b6b2fc5cbaac3e157506f41dd036d3f48f7758918eec891e965923e1cdb197fd3e5a7396354b9ec2f5b97b5aaad1df6a76300751fcfaa71b4fbbc7b4a4c300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000244326e971eead375d47afab0660de1f5fa14ab9311bd32cf9d159cbb09cf20057a6b489b4b6f9d5dd1fb4466d6eaa03be95d6f159b15fce61ea81844c2a28fae51fcfb1a1b4fbbc729c02f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022a1e117e5f062d434a9f102293cd3469abf9b7f31abd2f1fbc27483c87e6f773b97da4751a197264fe1c81d888fab6157701f70a1a40ee2ce4a78cf7becf150f51fcfb921b4fbbc779090400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017c01399dc93fcf207b0dc507908c716683795594d48aa2569e0281c2acaddc70930efa0057946561e1e978d4af38c12ec8baefceb3fed42b98c334a68b13e92451fcfba01b4fbbc723513500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000121e7020426b967c4156bad65cb13299f0b1f22fb91dc5fd1080b1d76f31590f764e39ee190b627f92a22356898a3be65cabd3d3ce50b846d3c5a4a326b90476351fcfbcf1b4fbbc744505800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021ce47055a543052cd77903834fbc095611a40bc7eba3f8b7d1d4f588528086b0a64d3e24bc5cb38bf34943db050acdb08d3d84fb66425d7408d26053767dde6051fcfc881b4fbbc7b7fa1800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f085e201804eabb1f97ed34777d56001587cb82bbf5d6e4e1ef51cebe758b676c391d7934c9161cd5643d5e1ee38636c8f696cd7be8a32685207e7cd6951478f51fcfdfc1b4fbbc7b8718c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002de424cc6a853b71f9196a3ff81d4fa7c2dd121873c5c63b10134af2a7369a9220cb7f7b9db1cb1fff667b54f7c8059584c9d796b80388e72c6ee5a8e781733d651fcff231b4fbbc79d413200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000294a48c67f81132c7d46c99f5f552816565cb2500f1d5d14dd9e00c59443d5153f952a9702a072ea5898cb07a1fcdf54a7f2156f25bdfa2b70c9a79cba4ea9fa451fd000d1b4fbbc71dd01400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023889ca2de2593c20977d88405ddb00a3f5936d3eebaaeb3ed54a85b231363f0697a3ac667f0bebfefab50f66dc81daef9dbbf1fd413eeb8499b0ed2f9630301e51fd00bc1b4fbbc7fe353001000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023e2ad1b976d6467c9eb4ab146ad3504cc0c229ceccabb4c067ed9154b1d2fa2497fa3b2044c9c1e8380841ecff9870511b67c7c618a4325e63b0a308a668da7551fd01c21b4fbbc72b987700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e0fc1cae16a5062bf55527d90c01a7859a7dc271edce2468551ad2806dc08f409653ebb7637d6a78d4eeb75edd126ef67d4e22ac9d678519b3326018e5b8774251fd02551b4fbbc7fb591900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001abd057869b5b4bba7dd1340852f97cb2af6b998bd636b5fd1f5a0a3c4c816aedfe7a8f63ef9cc041ab42002258fa9d5a6d4bfede545737403009c64b7835f02c51fd02fb1b4fbbc7e3871f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001853c3586160207cba66dfcbdacd5f671250d58296ca733f82fda70140bd302140bed5dba3ff147582d61a4ac6d34b48c92782ef39e9600ef099c18b4271e86d251fd03041b4fbbc7034de800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027b17679c8be5c9ff163104a37a4f94374ec637ea8387cd02eeeddc6abde87c7524fb690497368a832fcb58c8ef117b56682f3f88beda4ab51e089a959602f6db51fd03891b4fbbc727d63f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000273df8733bc7dba509addfd7546ec3202f8c815a022127e03502bc4844108ad5256d663c59713cba56c3fe71ab55c60799f6c62e70cdacb7d09bd9b567ec5734351fd04a41b4fbbc7ad210b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029c2d2689354d1712c9a7625565f8cd6241a3a29213e49e116d5e0d0c6eb317b4cebe3f6e50396f0e4942c4a698393051114d7cef31188f9089590488e5134cf751fd04da1b4fbbc7d2303b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000200336241733ee14e30b95cb8222d7548a88d4144a6592e171bd5816c388a89cd4449d4bba85af4ca7cee9aed7bc02c72cdbd8dd706506ae4efdfe31e4806a6cb51fd056a1b4fbbc73f194e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ae6d01d9d435a89552bffdf18a104b5a6a1f338a4d831ac3bb1b85bd07cb71661c5f09302ddd01c7d33d30fe173f8af202acee5d94ba03443cc8890fdc1bd66051fd06211b4fbbc7ae04ae00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ba39d9a1d54c9f8f06c8cc682ff1c80730c052c3738161449cbacac15efa08626b512b6d27157398920076f554b169fda1f16a2ec961c7ac7c7e3af932bded1d51fd06571b4fbbc76c6dbc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000217dcb433f2e6cc657e3a4e3b859454ffd0bae2119ebebbd2852dbe3ed5e14e028f7a06f3d317f8cc040ea8f2b7beb2aa023f2cb438d43c3f265d917ff7516b4551fd087c1b4fbbc70b2f0400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002faa36d901e998da057972d96d091ff0689e8308776bdc5e5d8f4e3744c50841bc165a4bc6fed2b02e84aee0eb7968df6949370a5c4ef9eb6a0bccdcddc2ae68d51fd08ef1b4fbbc738a60f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b55b29a69dd5045f1a50cdef03c68485c3a67f0c0bc55da73035ed66d6697cb04bdade3e48551fc471bf51049480c7da00f45c18ee66591fb83d101de2d82de451fd09631b4fbbc735549301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017fddd9e00c22fd46cf533162316290ba5c36d3a76164e59b8c976aac9dc52c9e16cbdff9ab03eabfc65677a8330c74f7aecabc1632bb58224823debf405579d951fd0b801b4fbbc7cc674300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000260372583b75ea6070f8206e22dd6cf6544056f64bb4716dc5436af0e30e9a77a2109818dcce42bacf8b761c5cfb721dcae27f16ed50b785227d01206667f44a351fd0e151b4fbbc73a036000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f9649255031be04ecb2476ab00b1279370aeb1aa8314072a52b90f83fa0a55e73b6dc7dae0cb2cb030c1436752acba036f7ac8549efd2b406993da8f9c90435f51fd0de31b4fbbc780a89100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026d7de70fb5cebbb393a2bd1601699821971dfc3ef9b07a43206bd86ca444f5b21a7989bee6fed977567b4cb650ac8d953cfef2a9a1f1e4bb7fcfb6466a0c3a2f51fd0e541b4fbbc7eb291e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020c27eef7a86344b34f08ef01f0571037434f94b90abf323ef860d969119892f81693037c7fc3f1723e26a64e155979880ad900bf65224cbf8bd31781de1d6fd251fd0f081b4fbbc7bd510500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013bb7d1e93e93a06b8c03a3b764f493e9e282fa817f61f2acf09c21942f5bb4f46e9639a47b74c3ecb2afc710f35ea354338d3c1005ef3d8eb3e837bb2c68e81851fd0f3e1b4fbbc7fd898400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024d227d029da2f41cfb75aab667eeacd421f809aa742e5ba8d142967b2bfbd6f8a9a0ef965e563947590d224dc1e46d9db65cd5b078e03909d48b9d627be6bf6751fd0fca1b4fbbc76d7f3200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000267ec9ab255491c0e58942d9ab1bf3f27bb0437564903f01f5e912e3cae2b82b0cf4fbc2d4d82e63c6c02c631e14862ec2842188d0ecde00f96ac7f7af89e88ab51fd0fe91b4fbbc720c02300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000140f8187dc5e433840c7192e215ef1d13b11e9d5abac32b3984b723907f7e44ddba2fd0a416018eba3a5888263465bfb0d05fbf5b138b6833a41bd28a06395c7651fd10021b4fbbc712900600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000181c2ee93319ef918c96fc8fd6207ad3dfaf3e9e42c8df44f2825d020dc962235f2ab2167df6b63883f8c1f4a4835390f36751c6de414ce7bd67b5d8bc12d1d8f51fd10bf1b4fbbc7cd6e3f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000271b98f9d560ea692eb52b8ef21c1228ebad2d1d6647c1eec4426dc41c2e1f6b0e4898a904381f0eb6d819cb33d819c92d5ee9cf8998b255ac2c64bd58128ab4e51fd124e1b4fbbc7b4b07a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000217b61ee994ac59f8a5c5b15d734b992a95ad9add4725f22bfdc5d00dce70339c5b87def0ca7c261294ff875f1b6d91f89d7e65d12e0e29a6a31871dafb9cf45951fd12b41b4fbbc70d8a1400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e19a5f11edd0ee9b03f6549524e1817581424fd26c4c4a5aba96617c2cef4ade3b1ab9b82e7c0beb98af67df465a54709d07be91ec604b9e089bdc91fcf257fa51fd13e31b4fbbc77d3b6400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016faf3137f9a1e7b8f85449ddcaa374eb08b1ed88e82956efdd36606fed26aae91bc3d314990d383d3072430cc96a4c0a49075d2c8f92183cd44841a49ef48de151fd14da1b4fbbc7d365c700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002116264d51be8c93190cdc463b0f53ee1ce8c5ace9067d3d1715356f4653d17ec273b7de14dc40503c8b2654af166f48b5dab8f71171ee2a3ac9fd4bea3b7d02551fd159e1b4fbbc70db36b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002409883aa6011e4ab55f703f8d333abe314157a89d836f7e5081e6b0752c2ab514e10655b3283145b4781fb03445315be96b55cfa9869cdf4a18ea27f2649fae951fd16761b4fbbc7df03d600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000211ac2365d1e8b884e918962b76edf23b5f88ecb0dfd4cd0f63e2daf319e2b2cd3179bf19f5119cabbbd8ddb0f51935a3646d77182d79b039d45edfd5ada78e5051fd17401b4fbbc70b125002000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bb56b35d940230ac199222b17f7c1a303f195526948e80226b40692eca0483b389241d020a109f02bfeb1592d6b7b9556c5624443107f61db3acf076de95838c51fd18001b4fbbc754aa4900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002018883f25cf56a41fcfb4162ccde1b7bf8c221d6d55490ee7cf27af81e41d6b79d037c61b6b9cea3784e1b594761afe4011f677a4327845d41b0acee97d0494e51fd18771b4fbbc7f0710a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000197cd87e16b628c1cb9be87579d6f263cfd8b9074d97eb3b6e3afc6fe9fe62366b11de9b8a475cfeb13d3cf602a516fb52ae2a39f7747b26833f84ae3a1931c3a51fd19e21b4fbbc7c6775a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014e9d390a34d1032b7e54017f184ccf1a80c9c4df6b413b2f2dba51233d2361a49329177c86ed0e91a9fdac07ffcdd077c4e500b20ab5b260fb5577e2b4022b9051fd19f31b4fbbc7c6f25b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023bc408e0b7e258057b53d0c813704e1a6c80a7ab2042513b494c14671453177f9741d748162efa0a65d16d3e6c237bb990820e0228a11de7982cd3595053109851fd1c491b4fbbc76f993a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000236b3b1062b17fb134f6c6bf37d6b9a63c45c0fb258755a3d1bbd56983bff3a01cd3662ca19d9af695570126492d468b1dc130f896fa43238bfc216f96a869ba451fd1c701b4fbbc7afbe7a01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000217a552201b87d8f77f50b53fed6c76daae2ec0b900f2ab6137bdfb0a447d39045e5d475dee8aa89009098dfaac8153f5bbe6f5027a35e178b4581164a2be489b51fd1cbc1b4fbbc745e05200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ece00491569aea6318cdfb185c3ceb082c7f06f1fa422a66c84cbe9f9f134599334d1c7742e7c89c58d7214ed9b015b5b57da893c883048aef38ed212230449351fd1ce21b4fbbc7449ba000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028c59ca07863673ecd8e0c5bc777d1e43416d88a10e708a9b9a95c56182e235d81268348b7f5971817a73d19b88a12e13884e0148e50006022a51be77e42766c651fd1d461b4fbbc73a996c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026bea924b58cdd3e73981eeaee57adc5bd327936f6d557c0f565b3ed50bd0e613d42422ae67208cb96f3dd3a7e44627e1dd4722651278da653aa874f8e116e69851fd1d921b4fbbc791a81800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001458f21bbca131888a01b29b3a48fe829479f83d268891cfb0a136fce033ebdaac9e7eb2fb6fdeebb5cd57b99d46f49834b17f33456ce1343d868c8dc138e28ac51fd1e351b4fbbc7c76a0902000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fec238e6c1c9dbbc915293ea24c27e38bbd86a5e6711f3e91326947304c629e00e6b35360f0dc704c93197acbe3e3bbb54d0d5a3b52c7b8664c5c61a00af471551fd1e7b1b4fbbc780e12400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001126f86f09559ced2f2b5f55b51394f5b9cb5b7b2edc25d3c466115a49db8a45ced649b52ffcd4dda8af9d9be0e858194e76c80f6e22e999a7e41ed8df1ec508051fd1f741b4fbbc7955b0a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020aa4eaabfbe95af39f8245bf4dc19d7eb400ae48295760be8ca10bb83d0816d37b6014363c3a0598e422db08fe998447dde51a7d1c085edeab3cc5e361a305ef51fd1fd71b4fbbc7ebfce100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011bd265a241049b8922c28cb534e2a9f3a8e8d7249dd292603f7054e95458688894ee11694b7023ce04273e2e249defcbcd930cd263c73a35293a5513a281b3d151fd1ff91b4fbbc794fd0000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024bd7710ec901be0848e788e845da13cb2eff43731ea5ab7380d8f15b2a2b50eb8dff69c5224a4fdf85a60cfa13222a73f7c1b238a14c3aea9c3c83a1525d71b851fd208e1b4fbbc7e1379e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015d7e611ce95f1dfe2e1e07e036cd0c1c92f92e3f52e4c1807f8bd763c56150f8aab5f8d35e1e6d389b9e8190652a5b6b27d8f59456e7964abce982f8c2bc428351fd21b11b4fbbc78e140800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025e1cbbb1a09df4961b54cc81d9b4c69aa21f88c845791ae83361d6d7657e539a6c7a9cf041bd2d6b58f39c322b4db93ae464649910c9157cc6547fe6b256a7c651fd21d41b4fbbc70a7e0100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a74d87a95de7bad84e08ec8e1a824cb79895121cb2bd10d17c85ccbe0e5472ea1bb1b05fc1d4e469201f4de367c1d90d3c71ca4be5e4261b2c1152db469dfe3051fd21c41b4fbbc7abefd600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021a928cd7f7848c3c0587e00fb40bae28e7a59b40c293b5e82b360f0839416cf8093bb4ddf28661f17a3e682210d943af77ff98aa08beba567561aa2554447d0251fd23a61b4fbbc776004200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000018c360d55e7491d6e725b8b2f3953aebcadab2f0c02ddc1e491e76cb3829d707e87fa16846d1c461bafcfcbc81855ddfe2a6327e5208a3bc4df93f4365c41e43851fd248e1b4fbbc7aea06b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023a89405454c56ad834eadf7d462b875570e17f76b0f10428dfe2ad345eab79f5e7d598d32ec73ca3408377d1156689dafcb0f6da941cae4ce542206ff564856351fd25b01b4fbbc723e02600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000019ddfa840db181348763be78277f062f09b3d2ed7366ed5e358ee5cecb6c57836bc00df17f91d157df6aca97c9b3fb8f5001b937206f90ac80d933c9ea4263df251fd26421b4fbbc7c31da100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d122e4a1cafdeba7acbd7598e34dab30bf482003f0584fcbfd9c3cda24258a78f4356b0aef6f6a218e7d680897c2feccae07bdd71ca37113e35f9c9d028ca96b51fd26df1b4fbbc72961d000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013d894eeccb7d537230d5803f942bcd484c0a2e19250b178d78159229fbd3e81446a00f559bb9505ddfbe59772f4d4584988835f0e270da7afac2fbd3b52a963351fd27f01b4fbbc7f8fd8f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028d14a42999af78269c9fb67eceff0a72861101666cffaa6b5fdbdd53a6914ea1cb1aa821de44d1b886478b253ee7fe49a194c6e1aa967fb04c1559bbe33920c351fd2a1d1b4fbbc7208e6000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000204ac1e60b2c90abe340c38d2d66d803f572ed039be975daa4d6d2ec7987ccb76be1388760d94885dce1c086ee61bdc6d55e1ce5d203727ba3ac431be1843c6cf51fd2a0a1b4fbbc76fb00a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025a274c34395d04603a578d6877755a16e02859867bda0b274e8d448f2bca3435109f84042fa1363ea447830fb3d1d1c6888f6486ef87fc8a414f7fdb49a45a8151fd2ab41b4fbbc7b42c1000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016fa958a6a943d93507bbbe3e1eaf72fdf64ba7a23af4b2faf90c1dd7aa7ef8b70b694f31305752aee0bf65f462004e6f0d58035e7151735499dad5e2bf6a943b51fd2b1b1b4fbbc74d8db401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002441f3bedcf78ecfb5027c3552970d7e4dd79dec9651492f71f5e3fed1628d7b67550a28f5e7efea2e62ad5bef29b8d0eadd257904e0203c94adc29afdb7a8df151fd2b8b1b4fbbc76e6c8000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022f55f0da8df5f19970f740a650c8c87c2ee569d7136ca47f2bc5e8691b048582e14b9f7e423f259afbec147c90714da6b3e007c2d57554aaaa2339fcdd6edf8151fd2c7e1b4fbbc7fef65d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e61d32448e4f86f64071db8c08c6b5203c0068c68fbcb01a6ccfbc733dd553ee08f86042e32c3b72bb574bf11748b4e482cd1cb4568f554f43ba5327f5d3e20151fd2cde1b4fbbc799b6cf00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002939c28ba9ffcd86ff63797f6bfaa908964d1657e2b3986ee1a81fb76cfc97f847c31fd67cc6676d1384b50949c32e0f4f2b5b0fe7fadb04ff2fb20d68a951e9a51fd2d3c1b4fbbc754bb8f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023d9e73023d9ee76ab17cda5aa73c45f75dfd30f918d0feeb210f90d35eff81477d6cc5af108bcf9931b02683c90d5847e2b2a6c7497700c16c2d43030e60068551fd2dcd1b4fbbc7294c7900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025edde1e86cfd814667a03b75f2ccd32fe72ba2e79f73418fe10e08170188bf328895e8707a7b730aa95676613a55d71630e111963e814f6c2f51ebabde8a820d51fd2eb91b4fbbc702872f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025f0d9f58855db59788e019c8179f62715e9d5446aa211ed7f9715604b7a976f6794a7260468580927c7a2ba6d6d63e817fe71d6d4b1ec8d27d69cea7cd4430e051fd301e1b4fbbc73c5d5b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fb353a87ac585a1f9161b78059b4bbb0989735f60621326bade3bf6482ff9afdc5b81cb22e0b22d425a5d3ef2c3f8a7caf635942a749d92b3644885b0b170d0f51fd32871b4fbbc7b34e9700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d7fa3a7bddf4ac6e378a8669d55a9138f4757fabcd1c6a84a79ae1b21c98d80ca91c7a5c3147c62b314692c5464e55050d2db1eb285bd39914ca33abec11b2aa51fd329a1b4fbbc77a710300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ae4e4184892d6d16b3270e2ad2028583883fb295d17ad5534f414158a6b89dc656b27448557aae10d358152458a715888d3e9ce11de49811d0c9f022bd48dc5851fd333d1b4fbbc7329b3500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029d936ed5c07d5cdf5bc332ba6dc7f81ece7b64c432c10b4d063e1b5695b98fc133877048e4d53c8f03d7f88972804852f79c9b6af0c60f29f77ace09194a8d3851fd33561b4fbbc78c674200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000259e8ee90e20ec8f3a767280eb68f5afed6271c88f53e026a51625668f99df75e1ff37976f16fbcc49801c1600399b2995d4fdad97f9cd7e3567c49fd94efc66a51fd33461b4fbbc7ea039e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026ee3b919481115207ded88775b0e9b70ca6a1b800088888fde675c924de8c912b8b6c6d4390fad70aebf44dea5f22b6937cdc4c05f667ab3db1c60c09d7a184451fd33fe1b4fbbc761447000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000274c0c8e0bcdcaa46f519ac145281e3757ff1d2e66241406f6395c3f75f5bf14b7a614eba38b1e41ca5a1374943c54e662c8c335dc89098fd9df34ffc10838e3051fd35221b4fbbc79db02800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021174797754b1458e113eb7c8be6e6dff7581d0b6d8ff967ec053f669148c2b5878a4b9705ad49c8af877fdc4602d995acac2743f99f6417bd69ba09b3519653551fd35171b4fbbc74f788b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000237cf9a81d615d1bc44d5d7df1f433de4db6ea479889f338fc53a6a87530fc2a1f9dad417ab0cd43473390f9857806c3eddc6b14fee14b94fdfb6c3cc49b47d6151fd36241b4fbbc78183e200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f2eaf948c75ce68a238163bc4d2dfab9b5f95a42d0b5c365808d7ce4e6b0f751c57bb72182c6099c4452289762801af6560f331a1d3a46ebaa267d7c45b790d051fd36d31b4fbbc75b889f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001643dd303a8eceee51ef40425c956a6a23d486f5e62d9eae92e120fcb52207de18a19d27d96d623b74f1631ccba2003719c5d48b03a46bb1c1da88efd483e91d851fd376a1b4fbbc74fbe8201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021dbed9be418b405ebc82a7d2b75accd0700d7d03ec2a3a7872360add6c4c61e0810599f92ba6dbc13d643b40c9d56eb1a767bc9314f5e45df6e77285e40071a151fd39231b4fbbc7d8761000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001dceb5678d259ad505964c3f618ff5fdbad40fa4d9463d639faeb3f96824cdf8f4fef1500ce26558bca89c20442a278500a8fe1b751eeb2cc9558f53f980a9ae951fd39311b4fbbc76de82d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029ddd79a17e2c5f96efb3948587c213bacfd32b3ebd5deff1314dc2ef23cc6ac6c5caf257c2c2aed78431d6116e143ccbb6fcc6cfa0200a7d7157742227b15b5e51fd3a591b4fbbc7c09ffe00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bd6024a93e52ba41f8b665f8713092c0ff389e359203c7cca4f9776afc0ac948e10c3bf5d9bae36c8102e2292cb3336226e414bb734d08bb33194f3a243f15d351fd3b0b1b4fbbc712c90200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021e6b63a4504be95dbba45b1c88a44533d5a511e81ea5f3ab814908698d038767d63d35aa3792f38f3af709b4fc570889cefc16d54c70345c1f94a8105db8cccc51fd3bbd1b4fbbc7403e0e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bbc9cd4892123bac28a139f01e91a977036a23f55213ec605a360fb80474ef23ab1971c56f1a3b84ccddb7913cb3590321cceb07705819474bf5a3139fe60cf751fd3d431b4fbbc7f002b000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a06c2f480fe012315bdba59b91ad3581b5f27d89dcee2d9e7ec55c1167e6c83b27152788770e28828e98892d8b59b71b8af9bbc4486452826cb75ee68eb206c651fd3e111b4fbbc7cd61a000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020005cb87b09b211f8472a2b2f081a0b3f2d3981bd1b3f97fe835445b4d83986044dc2c2e10f3a53c55b34230945932c86cecd612e380c58ece7330458c3759e051fd3ed51b4fbbc71ffac100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001922524b103ec182c20dddb7d716c250ce131ef21a16182eb6f44c8ce20d00678c522e5b9317fd34bf556deda70db3567ea6f2d791946af9ab26a7ca5c016da8251fd3ef51b4fbbc749908f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012e103eafbad0be5057607166f4f3ad80a386f1a9939dabe6d45769665a3ada8d6ab7135df6ef440121a240b616e5edf73e4b4450dae040bbe666c43d0cbe424551fd3f061b4fbbc77aae0b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015803b5ee3d21c3e11d3d59b03376e0ad2553b0f7a35f232dad3cdbd94ef6a75db405cccd25cf9d16be29f7a50788055a1e0f7cb545adf2354148241495b0cba151fd3f4a1b4fbbc7f2071500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bcf6e1e72944ede70f16b4bf0065318f478febf1804f7db33813fc0156eb27b4a46cb86d55c6ddf8be750deeed9f545af4707e0871b912377bf9eccbabdd337c51fd3f4b1b4fbbc7e1102001000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000262461a5f6b1e0d0e32f729e4cfea0f588252b31bc29fc7eeb9dcad4a885b67a18e0f3945b422371e6919b18093584115efc4c932198fd8f67089f98f39768fa851fd40511b4fbbc7673f4600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002741acfcd9a89847915fc74b99afe33158df1f024623504ed11be48624624e65fe913a9e6647fa997b5908ebdd8e4b7d2dd061dbfa4005ebdf566c3f75203cbc251fd41a71b4fbbc7951fa700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024ed233c01956b5dbdb9bf997e96c25e37ed1ed87d01de1f44743ba60ddced3c17728473a0d2315a68c1c43aa6bc39a757b5f22f43ede1ee1e2e909497251633c51fd41791b4fbbc726112c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b08cfe43bae2298866422368bd9682c154eefa2c30e642dfe1becadc7eca915995a4c426ce2693d9a0f0c3266214bed28d7cdad6af4880f7ed9f9fcc9ab7be6c51fd41ec1b4fbbc7ad310a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000125a92e123ba44c96276713af926d8a73fad5d87499a9e82e508b199a6c3a98b6a2e746de94e7469316033b1522f2c65b362d5459cc7cb770d4d5469be58153c551fd42921b4fbbc7cf026c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000289c0c1f20dfe2b52142695d1d40f63496d27b6a6c4b3f78fb86ae066a1905e1f4a0ab5178e80fc7f96215a43767d22f8d8603da5dad9a6d8ffa5a35cc58b01a951fd42581b4fbbc7d7e26800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c6adca1a23b12d62292654e82b2904cd6cfe7bd6accfeaf5329567116ed879f61e2e6ea1f66231b5fd6d72231380f23a183fc7040a185280b8153e1a266115f751fd42d21b4fbbc773487200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f1689ffa74453f36902fa3b72c93fdbaf927f3dfa42e0b9e4795c827da14aa3773f884ceb62ddedf78d938de6a30d049ebbaae9919d86f8c9b3368e9032e345c51fd43181b4fbbc7e4d56b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027fc171c138828792b1fe994e3d3f3d51892538ebaa5395f7c976b1f13a870fd91c7e773b88f40716b16a2454bed27e7dd6d4a5611e1d2583a60c5a02f0b4356651fd43881b4fbbc7e4dd5600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n"
  },
  {
    "path": "scripts/test_data_full.txt",
    "content": "00000002c800429c934697c3228799ee485d51423d3560d02fac1e321491bfe9502eaafa1748c8b5c2a4cf00e3241c72401faf1fed97c06c9f0a3f4e43cd87776d06af5351faec8e1b496c9afc200900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d571bd129475fc9c43195a86f726f595ecf856e53334eff54ce72f4d7f439bd07121364ae4144e2aa8507af42f14c60e3dab5bc9c1728e46c48a4d028e4271c251faed141b496c9a480c1f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ce1995f9b33027049eca6ef5a679d7c1a94196f61492a1405c54a4ad10cbc541ad463e5d87d301737a52439a2c1667ea91f3c1a8ce278d1f7f68d7bd13fab41851faed191b496c9aa4b30c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021358fb1f11c0ee897e023623db46731849b3fc842964da09f7979edc96a475c459edfa827ef8fdee44442dd5d5860b18066c6bcf306c663eaa3aa258b5ad925e51faee371b496c9ab0d36500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024302b4b37d6c76c409d2a0c1dc23223c10a7342ab1234e51bc761fcd83b86eb619048b17e1cc6f6f4a9174e3e841e04ace20ddbb12128f8e5082e760436debe251faee511b496c9a0edf2801000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020317a63f446c64b512f837ff5fb2ad008ef8f4b42d8b1ffdd493a0d57318bcb42f28497bdeb660c98b6addc3b7d8b157a5c95f99e0694eacc421f7c0206191f851faee7d1b496c9ab1e42c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000210ee5da9ef549dd28cde08983173217c3f3032d12eccd7c408c34b6743a2f1c1d0ec41ac6bef6d9a222cce76c3e3515b0bbdd1a0c58863763501afead93158a251faeedb1b496c9a7b31d401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ba685c46cd25d63af19f614364dc2ed9a43a3066ae909834313b0fc94d997d6635c69f674e89c567ce29e967bf9e9006ec1d2acbb3b1176307fe370599e4ca4851faef281b496c9a31d28e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c781c405ac64642eec3c4a8f893da9708bf49a590e59be2892da8aa2be5a912f9c16b568765a34e8f041434b264b3bc75b6501ff6d7f54bc101133f5fab59ab851faefba1b496c9a53225300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002548ddc4ba85d2df8e7518286cca4405467645a763f056f7eeff97656533d072fcf7561ddc703b69572dd685ec6b7f683a5ca3ec377e44b4bbf42d85237ccf84151faf0fd1b496c9a42d90300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c6db2fa5273a6900d8fbcf453744bb1b49414372cf4ace29f16d9304780b375d5a0b5575217037a800f84b34a273f47b8804d706c8c9270892ed1432880dc70651faf1031b496c9aa65ade00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021ab293794b87e8ceaa7c58122bf4fa08ea841cc15f577a6e226050833f0f274474d234bec1505f3517a686261d5600c2645d32bcc5315b0b0c58b0439596e7bf51faf1331b496c9aee93b500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e0df43e775db70ac7de93a56650ef06b0586855474585c8b7fca532539eb8db0c7dbd6cbd101347fa5ca564baf946b64b830b8a7a9ed2424f566c4f3c1c5e82851faf1491b496c9a72f59200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000255c80f7010299fd8b4e1efff9b07edb051f5964efb92adbbc9400c521142db7311125e9d6aa8581c02c173d30b7e62389bf605a015706dba66112a9502fc9b9251faf1941b496c9a64761300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b8bfc8f56b384f03e93a535674ae0612055f112b8a358f36bee7bcb1697b59dd3199071abbe7061151050682ae450cce2acd71b79a56cbe9313db59ff1b8736b51faf3dd1b496c9a62b11500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000299d3c3a5c64e752aa3271423c5e015b82bd02fbac08be84872fab70f3f5bce1a2e187e7518cbdc9edee9b953b6706f28c8e1c796754d20336b6b0738042c4add51faf3e81b496c9ade1df600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d713e9e50cf3c4f140dadbf878398717c996318f1d767f7accfc0c09a7ef395c26640d3f8e9d3cdfb0f48af6d0be7e73801ffe5c7439745dbb3310b33c1a847e51faf4e11b496c9a133b5835000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a9d24491d1a01fcafb680692b99f62dab53d073e1b6239b7990030a47388de838dbfe1d2cfbd0fdd931db8a000095beabc88dfbf7c5c09faa5a6a3850ef864f951faf5cc1b496c9a06582a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022481aee2e43003c06e7ec75af4cbc26104a4883a1824380be29d3744399203c5d57a1ace97aa3d66f5f46ab023855601fcbb699fcbb13a51071d5987c49544ef51faf7b81b496c9a1f208355000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e661bf95fcb102d9c6e95d91c754d5e46f9a44d8247e0060e438cbbe170090076af68394c9a0ad510f030627460beff9bd1ed4f6630b9d518ef6358cb66308ed51faf9651b496c9a13e74f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023aa75b93be847fde5b4d3ebaaad2546dd7692b1815b25bee221609bf3d2f46575a7badf661e10dc072fc7d8219935ad8e6798587a90af005aaaab8a150d295d651fafa851b496c9a27f97700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025abb33d96ee5292edba2eee0e8346dea30217f0c7dc3c15f52b2f183704a6911981caf4756a8dccccae0fa8c5d1e7b38e89e745c5f1215edbed3076df87df07451fafab51b496c9a6e543c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020dee07019ebd47c35e96d37d69e27f3ef13d0f81756a41b91ac0442718ad25ee2e725dd33fba31ed73e135c3d3849f41e1a6dead480766bff06b6fabcd63e6d351fafb231b496c9a71821800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f6c8c9836f6dbeb1bc6c9c74e2224f8fb7932132704bdd69fc0cb9d31ea414747e9aee846f57e569c5dcc91c4fb10a93fdc3038c91a22e574f484ca38eae9d7c51fafb2b1b496c9a3f9f9200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001bec9bf3239ca0920d27842e8e96ac4bbcc5d9460f840cc6ed013e1611b4532d6afebb0cf574887674d11133aa656885f591d50c90b7655bcc066c9d7236fa42951fafb891b496c9a85e3bd00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fcce0384add10421890a35109335cc5171fd0b3abfe3d0fab158026870ffc462d9972d25517735317a7a3eb3cfaf7a0c7ed63c19453971dc57e3df6d106ae8aa51fafbba1b496c9ad2073900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002aa0e6ccfc7974fa8f1a8e655da9185c18cf628aa74d71f7cdf944e8fc450dc79bc69e21942a8c0af06ae44a2225ccb7f06956fc189de2d717ac3b514901adeb351fafdb11b496c9a8c93f900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021600319f1e06e02c284fdb6ef3e816b5400009011382d04851ce2897a4c00a2946a1fc16ec905837513a6360cff527ab43a9a021f8263fde7f570d9649294ab451fafe211b496c9ae3230200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000293fb31984f83fd65257c5a479dcb7f3d36082f07a6ae7df3340f59d10339698002615323f01d4ba4bb60b4e258d4e9ef1fa4bdfd50c43acc478614cfe31c499651fafe0c1b496c9aee23df00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000019c4bde749f33c2e1a051d6c61c030fb06b0785a29d31c98ff4f37bafb8454d1becadd14a7dd81b4ae48e2c49fe8ab246f94a663cee131a81ef87f942d67a40e251fafe441b496c9a0f3b0280000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000106c945404ce2dbc440fdc0d9633b423832cf1b441fd503173f2486d1a08b2491ad77e906b87cb36b7d94a74f5a223766039178e7db49682b544ee53ad688de0d51fb000f1b496c9a026a2800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ae0d4ebd899f12f446809804ae3dda9c8bfea5e6acf80a88456c8d16bb7f274c8749d98838cf725eca769ae68411a4533b37191a88b81dfab5f2c3c79a3ee2f851fb00591b496c9a3dc80200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000265635df3c870d290d409a0b2d6d2e58e2fc5985997f86cdeabbe944cfa29d73928417da2c98be85b4251a4e36bcc84018a58af41800d93ceec53aca6de92f9a551fb00f11b496c9a60b45b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001515dabb0e77056baec7278f97222ca50f1f571ea90b1892d3338b48d3917e5add4a2c290bbe5fcf81772878607b4adf52ebd998f43836bffce194d60aa2eeb8b51fb01471b496c9ae3012600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a0f030f6c93f6f216f439033ca1f6917fc2af73dd8a463f1cf7dfdb465fec2a8e60655b389d3b18c05984231e3100513667a7497b1c3429a3d5f0a17c23a2a3d51fb02561b496c9a1fa33100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000109a34a587396b60fba9a1179a9895c8f9c8c2e9a1e149b6c0f66bbe496ffeaf0abd0ad3b57595a7153fbbf74b68ff378b5393e4fc069613bd81330cbaddfda9051fb02981b496c9add95b700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f1a6059a66c81f54cc35f142179aa405e56b54ae1422a130d6514231aaa05ca37359b0cfd2c0666469c1a749475cfa669fadb3b6834017397117f89b8840168a51fb02b01b496c9ae8753601000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001619ad66ba3c1055fc0108df52953fe56e9223b7f1b260b59d2da9b3cc8fe4f72ec6f909e6ef7567062442629af618fb926a7393b549cce27ff73108dd2dd3f6d51fb02dd1b496c9a60781100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a2cbe6ea7ac2b47215daeb47a718395e7611f8efb10748dc36081b2f505d043d2e775693a57c575c6fb1af72932a515bd26caf80aab5a0dde4c1b51e4b85bd7e51fb03a21b496c9a31790180000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001dcd762cd5fdc3bc2a4e27fab305cacb1bec81fead10a938e984bee41700817ca4a3e8c4d0648dc8681d76349bbadf6b9bdf84c8de81c9f6488bb65566182ccee51fb03d41b496c9afd7c5400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d7be028ad201c136f0022de600e9eec8c82faddb315221c703cb1068bde957a206d5b44c101fd3c204768cf6aeecf85a14043f69bdf45893dde90ab1135e823451fb040d1b496c9a18130301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d1d62ba1eb5685a614a29167fb4ff2c478599f162d2b7c037f4253dbd6f58e2f617fac1f45e9b7270d9ee9682e28ef318e9494611205de7066415add4e3c138c51fb04671b496c9a33516b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000276df33aa821649abced424e3195610b4480964d0127564fe562b6b10233d62d149681133ebeb2da88460241c82b1eb1e108dbbb97a3e8c952ac0acfe9508930451fb04cc1b496c9afc3b3300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eb27047b60592c3fe46589945f40f631a8c48baa2cc264e0788bd877e54486ae8dba93dfcadcef42ccce66025533511ac30f8ff46a4cbcc47c4286a2f0b3fdfd51fb05b61b496c9a40109900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e5169049d4adde21df2f17da3bc4210338984f2321e94e3619f2becb3a51be7da4b3b8c48923dcd813c65bc4c2d4ef341492ada6c2033d0eec58cc2692bc874351fb061b1b496c9ae2152b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025ec972109038207f25a48f4bd2c510a1d946a5f959cf2561ab83c3978cca533de64439955c986232aed8f7bc6aa2dca654e8a6ca8ac0c11b99f307994789f41051fb06691b496c9add001400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014d322538ac127b5f41dae018d140a3b5a08fab0f3ad18f92e162e7f2c33b1eed8d58c5f8a2fdb4602ac3a04014a5845ae36863e5b0786ac1e1cea05a277f8afc51fb07021b496c9ada340700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e178c5f4ef9c395f4570329ee9803c8271da256abed7fc6afe579ab4017c8a97f57079cfa53c6a4b7e5e8cdcc252a8aba11ea09b80faa34a11cce8e9184200b851fb07911b496c9acaba0e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000126b07330c03327fe49725ab1bb2d4aa634bba5c105f31bcfe146d01fb9bf2d03a23cf30806db84ac90eaad8374b6088a9119e283613765e2e72b3ecce512510051fb07ce1b496c9a2d8e6e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026d8ab7f8bf3a4a1f13e66b838af7bf9a2a11891193234e8a7c1c8aac0472e0d89acc69461af0dd923cb8cfe656ad2762a6428ecdff8d664d9ebfe647c3ed244251fb09981b496c9af60ed700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a2bf2dcb20932f49989e3f9a79020673dab713d1e4d5dc8aaf46cb14d9e9a1197e15fe1614c2fde40009e928ac3840307e71e37b09b170cf90f3ccae815a81e751fb09d81b496c9a3403b700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002776deda2570e41ffbe48932fbd8f6ea032ade0a9e14d0c1b16df6bdc385e79405739ec01a0a22554b957a99aba4136d4484ea122562c01b85b96fe045c85b4d051fb0aca1b496c9a859e2e01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002293be79adce53589afc47fd084e07cf4c18f4edf0a82660b143d6af0f48508be8b1a2f5613088aaf7b9bd7242b98fef2d92328f1cc9424f75252df80fbc4501251fb0d2e1b496c9ae2eaba00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000226baaf2dfe9b57c45000f5a35a8d4e01faf0c42b43cfb0f779a0f2b9bbf3ea2cd8057ba951d5816a4bff13705ce46f3ae6ce5204eddf3c25b91483d5ca6a873551fb0d5c1b496c9a37367700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000019933a18e493f7a8e71283411fa48e7673d654f4c9c6631098fbcb4b3d994a0efd24388bef0b7978db144246146bf0c3360c6113d20287f2c2c9b2a7ab610c67a51fb0dad1b496c9a135a3701000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000161b8a845c62d13dc186252d738746a4cc894d964df9e1bcc5085e86863829f326268ca76f5c82f05416cc07e42951af5cf003e350c20c076fbb906e1e4e3e3df51fb0e2b1b496c9a9ea62300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020f537242939f3a470a3eaee4300bbfd931365f4f37dd81c8390b2629d936fd0421469170824e48165406586f6ef63b6944ce58d6923a55ea78b811dab33a19f651fb0e631b496c9a52f37700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f9c236a84a76ffa477ec5b1c1d8ebca4a5efe9a6f882884da064b59b05d5e317b1c9105f53887eacb1e30fc23d0c79abbbdb3748a01db5082bb11b154982043d51fb0f091b496c9af0f8c300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e7fff3b14ebba2653845335a5d2e4634f4feb7f306716d1958fb93b58774ca245057cbc44571c3eda192f76c1614b1f66ad5c3c1000b13065599cf736c46f9eb51fb0f821b496c9a17651500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000144d9c326e50eb1f0c37cb30344514087848fcb23a8f59a60a7bbb3de3be99168d4024293486006ac489282257a05e03a78f600a846c5e33fa831c49482d146f051fb101c1b496c9a46382600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000208669b92deca5b3461d7a0570d3ceab299401c89340cabcab2fa4e84f7fbc67b74751e9034cf5d38e183de2f84b8a7631fd0e66ee4a30ffaee7e2ee07cb9dc0a51fb10aa1b496c9ad5357d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021dee3d21d44f181f6dd68e0405c5d59d793f229f521ca3913973a5a172456e3abc0cfac9213750873e4be08a58e8ffe9c96312ee0267b906240bc626cd11dac551fb10ca1b496c9a35a9c300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025ee076ea0bd5f5c0f34732ffd94698a03ba8017e1ff87039578d20bcf14cc74e405e8b58a7c6e2fe90f77a4c037b62e9b18aec551cb438e67cfe4532be44402151fb11771b496c9a69335300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fd3b6e817f0266eaccf0d65622c6816741c01a1caafac8d99fd313465cb72fbdc55246eccf394271bf7b19735d9b5b2c0a612cc5765eb8b18f3e3b65382ed9a851fb11951b496c9ad3187800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021f07072d615d25b7807a5af28cefc4d09fa5792d029b86a614fb0e622334b7017276895d71793faa079f0b364845c78c3b50ee87d5e4f3bcfe1149eedd565c8351fb12241b496c9a02fa9100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a65aa3b5741550995cacdb16c0ca8fc87725e18d5a02e74f0df29384d0151c0c48632a57e08771c4518e6dda699d6afa0eef6cf416a2fce409804e29a59c4cef51fb12341b496c9a6819fc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022e43c0afd04e2678324f2193b04e82db60f228c9a0f535e9af7e433c67d9ca1eb29a99ffebfb2f3208ed36f7f296cbafad12802093704dbb73b65c3c49e8e9fd51fb121e1b496c9a24360401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015f63fa829c632882b0c6675904b576ab2408e797e3b1d90039d50b92073ca5e9c35508feaaf5cbc6f443fddc769920a01fc4e1e8742be9568001f035d397c4e751fb14981b496c9a7a1f9100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024cc98a77b57e6e2b04c2a80f48c76374be043011028df7cf96cd7236b24259a8dce92a8908fd3910f7e849516b2275b1e2495b1aa7920ae0463ce03cb9aec53c51fb14bf1b496c9ad3218600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e12f0d8504b4bae32d559d8c5c5c81212772ba6210b5c4b502fbc0c2429d7ea3345c7f9f05c7cd5c22fef12a77fb32686433092b7f0345fdecc8581a61a16c8f51fb14e31b496c9ac95de300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000220d3e6dcb786914ba809af7b6dfdb6ed0aedacc42043fab9fd98b38187895ca153d23749562a589b59b6e465eb86fd160b03e9b05663dc1ba67a0dc13d7dfeab51fb17a11b496c9adc862d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000243aefab3f1fbdb4aabfe83e4bd9f0e9403632c004b571b4e3b4d69b803530e33d0f6f22faced9af822a5e4d3f163fc066041c11066ec4bdfb04464e5c5dd8afa51fb18b61b496c9aad3c3800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000176ab515fe7ada88830d30b62002a21547685648d3e09cdbb54df8ae45fdf98a3fe20a7f09462fc5d14ca00dd45a09ee875217a828951245e2ae2e04ce637e30151fb18f71b496c9a33090600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023277a238e4fbceaedff43d8cdf82ad9d4968d1adce911cbcd4bff8cb6ee82f2578842b47c70f73f56cc775ceb93914c683b47ae224152ae6a64837f01437e0ea51fb19261b496c9a25f12101000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000136cfa1049f5857095a0b341617eb749e676e1b2790e591e9afe7be74641054e37d3c3893cbb2c2b8781201db66da1ddd1644f262d501c9c5e517661968a3306051fb19311b496c9a00e54300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002716f5f4498163405a8dbc3d45a1e32b1e07f6fa490ffb7ddbed20781ae290433938b17e84fb65dbe348b0273c493467b5d7c458e22aab9839f7f5ea35c7f59e651fb19ad1b496c9a3d7f2200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000179cc24e2ba434de3fdb526e966a0c2f585aecfbc50d0d05b9bdfe2ba6376fca0a40ae2877194749577b2a5b2b8a688063eff1db2877444b9f55fb7c2cb875e1f51fb19d91b496c9a00008b48000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001bdc9f009f8a629f7a6de61f669f6c6e01915b71bf8c240a6746eeda5409c4fd6daad6f7d47bd299a7187d925ec80ce2c736cddc9f81d423e712203b66702697e51fb1a871b496c9a970cd000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000018b73c13d261f67df140f85d11c73eddfc192bf8525b7a7320db99a9d0d9ac490b8ef835c5fc63e432f44750c6760dcccc28a792fdd2876e3c5be8c594bf756e251fb1b721b496c9a95fcaa01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025290157fe8f6be2c9ea6891f653eb7ec719c83117d5872d492b1ad7fe796dc79355fce37bcc68c4bcf229c3ec0b7134580f82208dab1ca95267b42a67180c2ca51fb1ba91b496c9a33688600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000169d72ec713093b03fe1546ea9c67ccf35270296302c4dddb5dacf1ce975bb3564bd45dfb748801933814a0675b87815b27c732c42df3ab2d2b2ea349eba4f95551fb1c541b496c9adcf70d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025c28dfde6e29e8b2435309fb662193f231b21fb398fa25d595c88b2446830184d34279da08b6042408749a0ead28477ef1e4c9f74a11a08a4ac936ffc38489c851fb1dfb1b496c9a428d4e01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c1883dcddae23d98e2900e4566cdbe1015f2d521c157432aa75e57b8bdf7841156e91e422154c0b4580bcf773bc15c7922dea85559dd373094de0202b2907bd251fb1eb51b496c9acbb79d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027d7609fa757ec690334f5e1c7cbcc36ed9cda42d81962baa6fb67393f962ca008c82cbc174071aac1a3702e0dd214ca4f422811a168c93333e6881f391dbbecd51fb1fa21b496c9a30cd4d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028bdbeeacd2c3236d80d7b7411b9ac5359d910f3d3f0b50880d79bb24932d8965f5e6d46748ce611f385fd68a2be5a6882e29dba1e539f2cb350b98698bcf25a351fb20671b496c9a1dfaa900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010829016529469fa30c13a4a200ab00975b0c4b10e9ba115f00181d766c4c6f735e891098893bf1c2b7c62f59aa8c03a604ff58de9f494720a64633f90351fcc051fb20681b496c9ae59f2b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021e94496eca95e7a82f6cd2053dc8db71e598b5204dba0b30778157bded7ab727b7c1cff48f29f2f9d43d64e5fed305e94bf1a08770dbc681e3ed84accbc38c2b51fb20a11b496c9aabf18a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011dfa5184717875a38f03ea582f0c6fdf3e4a883ddc61f4dca30519cb0f56ef089ef64bfcdba06505af989cdea44e7c54885e117a8cb741927265de0bd6c846b751fb219f1b496c9a35993d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c8cbd61d21b9535f56f8f732d33b31ae33f00c3235f38a97e52c069cdf756af22da0a6d7238040e15b295ffc8da365295e93ca118caf669095eb520c31b2bb1051fb21c11b496c9aa5d9e301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a19ad5fd8a18fd7dada9264f914dcaaf3d20e72524d1d11650075572aa2094a769674789200f8446f48f1f123edddd95b65f4f166679418cda3713020547d32851fb22511b496c9a2b8e0000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ad184a08fcc7f936a0502a2b47b5e61a53b50b783f21fc52c76b8fd507eed99a5a7f4117f3e96b4c7855d40f575fa1532ff8bb43a6e2031022eba80de30097af51fb223d1b496c9a986a0100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d350ef43b72cbe24cd5dcaa8aa3e21e050f9ff115579838711b1657dc6c029806e8d8c2c367fa86d9a915e2d71250c104f5943af25075882a8877279bdfeec8b51fb24261b496c9afb230280000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000194de1269525150086613654fe64781e2dec362e2656af009bd9c62d652e8f4e5e693eb0b9770cf286e8b5efb6e00f319c043c53f2a4163d7ba300d2a89c8c6b251fb25d51b496c9a794d0500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000124ad5ef1dfc8de20881722431f61f81d15000d64c9809c15ad27f9151a0e29ad4c50555dd5ba06f8113afed7d9f411177df06a7147f19e58915d0660da66ecc851fb261f1b496c9a6a74b399000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000223d9e32219a1d345a3be6d1480edab98f4f54588286c6c7aec190e0d262f6632c2eca7fa60a396c2bfcc8f9212234d17fec035030541e41611320a06f1528b7651fb27071b496c9adf024500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002303d66f836222684758e72fdb2d87c4284c674184c71f4c8fd623b9912e3dacc567794dff61ad787b63fab70ee8d355a940d9ea76c9212da3ab1e6f4279af6ba51fb280d1b496c9a0d969000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000143e2a17a628a03e6ce1e533e2b4c38a597eedce757041f4dc843ac5a5a51ac9a552e3bdec50b605f374c4a4bfeb84e79b04881c478e7139b20c3cdb4e75f1e8051fb28621b496c9ac7f8b700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001880f1bf9f08663b9b692cd217ce74b1f90ccbd9e9c8ba4a0799a46cef5c978e5101f2132a113cbd1a3c3ba564186002dab53f660979ed462ff26d33876ac79b351fb29de1b496c9a58356b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000206a3b40017272aeeeb95ac46bdfefb5d8d7b578354be60dbee110c20c3a187a8840a23c71155245e135fbad2215733f90a368b1e39f1ee934d7612e67615bf4351fb2a0f1b496c9aa48f4600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c6d31a0ee6845924111880827fedcfcf3ff4cbef648102137642f61f114d62540e083feeb0b7af8a5113498e513095b3064c7bbe7071e4ee1a4f0e1c58c0c41251fb2a601b496c9a44a76400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023db8d84ac828b40ee0bc5ec8ec063521b7cb29b837d052dbe8b411ad2fda05ec5e4cb038e29944f6b269789a3b1ca6811be2d5667329300779652953a0a4359851fb2c121b496c9ad1cce900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a107df7acc5bbfe6e07498e965c98aa34aa36733725c9a9e2379efca527cd6abdbdc8e93a2bdb700920458b5dc4fa04bc495ec146be9c76d5b52e0270a4b0f5951fb2d291b496c9a0ab04200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025a9671f9bce69ab8c0889b51682cb10cb9f3f6bd91f38b31c780a0b7d7c3f9ad5b22d17511657ef5559d052cacf6ccf0f8b92676def61d6f60fadb6b221b72cb51fb2d931b496c9ad06f7800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002583068209f7d111ec9d23fa8210bab54c81f9b4feb4f09e3bbf8131d75dd293dc37aa1f87d9b61cb2035ecc19df8db7ef858ef17b77c6cfb42d307d6325af4ce51fb2dfc1b496c9a4a4cb06a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c48054d1f7f375056830b68d3d5ff54fc1da861cbea7197ee1d54d86577b9e02591ee7d6996c522350ee5b07ca0b6125bb8ae391631bca4ff14a7bfa4ea9c81351fb2e701b496c9a5b282300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b04653201c4715b1acaf1110a78689113f3ff942a1a4e53f98196eba82c5aa300bcfb3f952d053f47e31e4856b550817d55aaaf765c8b5fec2ed87cf43d08a7351fb2e7a1b496c9a8f428b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c17e8a4869794417038d2cef371d883d1f78f49e2192e6da64b76cd0976f31916633d55b9104b50076b3fb19adea492599cd126c7c88de1eaf27e47c483950e551fb2e9d1b496c9ab74a3a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001753fb5e0ccdecfd27202642958dfd8531fee7ed6bde59cdf949631c193849a58fd39cbbcdeb3c11c7df69274fea3b91876b269fcfee09212fc1c64ab2325375551fb2ed51b496c9adc4d2800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000231ab1482dd1cff4494c2087a9e80c0bcfaf9676b1835ea862e1562faedeb7f02b3496a0b58faed1683c4f77a7f6dd8488a9873fcd60232cdd779e7b46bee3e9a51fb2f271b496c9ace02ad00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000244c842e62828f21c574ade834ebc26ed707098759c7a0c96d9ce02f90cf8b7599189472596f7e9e277c93792ac53cb092adf77d1921653a0e035138e01d1615c51fb30501b496c9aa47b6a01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000110c254b8cb73d483f34a0bb6adab92ba8cc616753e1dcdc669010c4515d7f7ce1888b2473d90f290f8774f480dddf33b03ad0e28611e743f9fa4914433a4497651fb30b31b496c9add9c6e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a8f2e560203657783c90eb00157084254cd19880bb614dfc748179e5fed706b7ed5ef6eef45c9562a7f9626ab7c352664bf6641ca3b7630fcd511f9ae9306f4051fb312f1b496c9a1150a400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000284f972f56d2052146158db6700f81beeb2b8b00b7832194e764ecf2d7fdea8416d3b160c25e17878f2ea2f6e7a82f734b45f6bb360d9d2cfbc2df54fd5b712ef51fb31c21b496c9a1aa2bf00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e03502106e792b2e7e6bf9b114dbbc5bde0ecf75dc5c62cb5ae9d4802d38bfbde6ae109dd41db4e2f11a53a6a67146bd7b19c984162b4d22f86e23a0816bc3c451fb321d1b496c9ad8b92a01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000268eb28191d1dde18f9f00d563e0a8fb13899cd576e908acf48dfc1c9c3230a731ccd3758e420de9d5d85a1c4f16952a5b96eb5b59ed5108ce388b0c1ed0b30ff51fb32451b496c9aba0e9c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000199ec7a60b623ed8df3088def1aac2510ea9f1054a245860cb1858cfb7489e2d22783eba1c6388aca60823ffc647d45acf789d915ee7df1f17b6fe7e42bbfe78851fb344a1b496c9aad340400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026e066204992d1edd04965264cdffeeffd149c37f73970b941a4dc610e084248a19df2f77f0dd2863413e28dd258c260e205fc686adaf922c0c26b7bbb9fe038851fb34c21b496c9aca3d6300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001bc0667d7bbbcbcbcc949325acb581c7490c1ecbe104bd1d8e78e691d238960d368b517b618bd3998805f7c3e07d5a16e430129c1b95f8450459d72a14384fdec51fb34d71b496c9a9f855895000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001bddbdc136ce15f61d9f3a1754f7f181eb0a74ee99316ec7b17285067f2459008b8a0fb69835c30cca7b4c49d401a8d8c426a7fa85cdbcfe40e33ab9b27d0596951fb35921b496c9a27250180000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f7f215d345973da349ec018c691bf71585022cb18cdea09e21ed5a32a02f9f1cb017c73426e3a1e9494ebde095b99a11b5ea45b6536f35af084f15c8bb7ba87751fb36321b496c9a03b0a000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012df2d914f68a67ef3d426eec0bac60a4eed69c276cec591c69caad43dcca276f38628c35a57267c8c7f20b02198edf152ad309fdf80d8228a8bd5a8af86a5c8551fb36461b496c9a4c241100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000109c5dc65caa1de7e77b4e020e35a0bca94b7bc4d7bb4ca88cb89f57049321ed9c21a17b45fe6de52bf9f334759dad30e13ff08589f5dc8863c4d72e2cd645da851fb37081b496c9aba74c600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022a3692165700b7253eeff5ddec958ec5fef3823e2db7396242d5576336fb892e8cc69e2402c9fd0e974893b1b0e3c765ee38a4d52bc7ba728eb1dae16b9621ae51fb37ed1b496c9afecd5600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016fd9c5c23ebe1c4b31d412d12662ad7deab74e239ad1a92e57b730ef5d5e3d1183187af63e0efb62144675ba8312f93b59af08e71b0d8609d62b8a446069b5a551fb38641b496c9ad281fa00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012a0c1dd37307435bd5cce35bc7827a1ca839a2a5c1767e1b532f7712275f23a85ce771c7bb2ec37dec537f469be501d1645de11778b003dfd524420ad30c89ec51fb38e91b496c9a39141101000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001eacf34a78273dbcb85cc5a889eb36d17a4c4dfa1150450cda70fe78e48f81aa9d5df2b7d15d58bdbe9185f7b9001281789ad12be434dc0deef46f5b566fbb21251fb39981b496c9a37303100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001cdf890518fb7850a996c33dc62ddc921bb3f9e72f6c47b5925722e8cf7515398dade01452995951bb7fca46536f7e04571e25b9ac878b899552bf66b68d7300551fb3a1f1b496c9ac23c1e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a2b8a04dcd328a4a50c6f4bb5de38a9c46915a6aeec006d4095392ad77e105601e5fbb91878d774746c082f27de15173ba8bd96a91ac44848ce49cc243b2ae7451fb3a471b496c9a897c9500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a0917bcc63fb03bf91633d880932dffab3387b30aa940a047edd062c35718cbc9d58f4ebe8961d6409941f29a9c75acbf336a22d4cbc5be2f4ea2c4d311f8de351fb3a621b496c9a24230320000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023a89308dd54ecf2ea266e95d74b59e4acac7b62feaa0e19c7e1524b568ac3bdee974bfa2da15013b9da035d1b26d94dc590fb9b288fe24ceac6939f0c9a8a01c51fb3ac11b496c9a86d29b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000230bd6fdb263e8f1a8e38e3b9302f758e7447804b4c20d907256dbf74fa7d7ebcc33f619d15b161ad67712bd004c5aba1feb6cbf157532edb2726acd852a2fe5751fb3d141b496c9adb75b000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b9370e1c6878d2ad5def4567eec0d895f70e7c17c1e4865b54e6732ebe10f71afbc3a99050c25029471a47be584b38d4d615460ca0c1be0df44de8a3a9d559d551fb3d5d1b496c9acbf61e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028bc73f1832083c975719933c5a70b5cd14879068204b76f6cd8efce422b90873b5f0119d9ae006d038fabaa3b56c1ce687d472784c0b37efe32cb1ba771aaa2151fb3d661b496c9a970d7500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022cfb000e2f93fb39dcee81a570adf4ebade5dfbfb7e24a665222912440a5d256f75f421d33ffe5dae096a75fb387e9ea3c0ae7c44f1bc98841776f71baf6d78751fb3eca1b496c9a070e7401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000221439764988026634b5f843e24d966f9a8977083ac8675e01b24611760d1adaf2cc027140d240e9bd84fa24c4fc6d659f040f31e871cd4cc76565c8e583434a051fb3f3c1b496c9ae1a21000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002dd983944147857c138de4885a76d1ce30389e90b4656c7eeadd500fdba77ec5478220b2f15987f0e407f6ffd63bb1ca02228e6080984d78edf3d2c2cc33acef251fb3fb01b496c9a84828700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023888177249b603b7751a89a980ad96984b78516a4d75a850da2ebbcff312226dae7fb2a0ba848ca6df7a9c233ca4a66a6bcaf3a32b8b4aca1e5035089037492651fb3fcb1b496c9a81293a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d4be5ed2db51f5116315c15be8d1f4cef14a97e3be6a9ffd18719123f87cee51e928a2f5062465d4bc369377124c9cf3a2d66c50ef2e623e0e7c850c6dc9295851fb40161b496c9a8e3d0400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000107b6a125f88d7dc98b795c837b9166fb0b31f7641994e84cc2a025a45e8ed27c5cbdd75020fb41cf1291a1d70cffb0229dd4712e6225b0e7fa139080cb29c07d51fb40d71b496c9ab8002901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d3129bdf8253f5b31343e236865e4286eaa4c556570a788b8a19bbeb8f111895402c567f58d68fca15dc214173a6cb6c0b04c32e6001dbb15f0df260510b510051fb41161b496c9aa2ad8900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ac90d85c9993b3146ef592d6ff3ed40007f0bd6ea14567dac02b32e7712822812828253bbdd970bbe15822b1e20d26d067c2132f045672be0a76f4566e9edf6951fb412c1b496c9ac3d3acaa000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f543e32800d2deedb6fa22d8a0e64e92e35fa7649328427b18094ef671da5986d304d8f6d5eef51f7e396124584fd73e355679025f2ba44a87b71d60c20c86db51fb42231b496c9ac5704e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002331c1a2e05bf8d3676309aaef3a35fb459f45243f5f385502d2e8c7d3b4dc4af1fe2d0b58bd30a0b10f8f0e1ad9763ce3d3254bf9a26b0029f2562e944c6917151fb42371b496c9a41b67500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001bfc07a6ea0f751ec346a11e43d91eda855dbad4ce4c04c57c4805098271388a1387d39a09a6e7e4376f6c91dfc1c6e337a86057d85b0ab05ecde8ef3d268f91051fb423d1b496c9ac4f55f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002abc3b7e951adcf7253b7356d90ad6316cd19a7b57e990ea0e1fffa12b0ba90921c56d5540a55a50018089de672343205e008f5663de54df615b5f765d022a8dc51fb445c1b496c9addfdba00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000185b0db266bff4d14a61117b6779e6f21e48907a825b500445021cf4093694c493b39fd41dbfdd3a1a656296deaa37762b8f9aae7e0f1d7f07aff992140c6c35151fb458b1b496c9acf90cb00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025485a86297e3987696e56aa3f89d837e90b93c2aab587d0b74fd517f85dca9c0361eb9f86b1ff6170d730b19de439b0e6130d3053e7be45aabfca921bf8d831551fb45e21b496c9a93818500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001eabac6e4143f7c0eb95633d9c46ca62eb29ef26739f339aa09558ac405d066b9570bcf903b8ca7a17b3cb2b152b37ce7430c744968135406d81243286f338afa51fb465b1b496c9a6ac90600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d8cb6baa83ae030162f05373d5ac33c5c7ebaee2ee264938e27280951824529784c8b4aa63996431cf84aba0ccf01fd0448eee9ad2b652d7330a9149d86e839a51fb46ae1b496c9a0ffe4d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001082e464bba46e19f190744d7afbd99fcef79222271593312374ff27cf19aeafba4fdeef8824cc05c87c11743947b08981ac774030a69858bd61c7fb91a22223651fb47ea1b496c9aada41800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025358f75bcf89d4d401b7a3f268dd53be28de2fe9e6f501ffe8e27ae76f1df96675e7c74e2f17771eee8c7092f3bbc7112f4e885d3acc89853cafe580bf8e62ce51fb48301b496c9a237f8d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024be0590b7450f23f64121b4222d59ff2ccb84fedf7dd6a8da7ce9b6733a5a228411a3a1093b4ff9b62d2914dbe484e8a7225d60dd7783504868190d3265d955451fb48bc1b496c9ad2563d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015451180aee175304b0258544c1d2fda77215f8274504187e51f1a76fcbc1bc8ed42a0ae899c3a8a2345d5e503cc98e5fa086f1f17f79d63ca6e7758abf2e291651fb48e01b496c9a02540000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027826a3c30bd2b55be303d2bda621a04940567ce9fcfdf940a573d2bc43e0de254e441a93dcc341492cf09918632504d9cc750791184b7b33eefacd1865591c6651fb49691b496c9a7681b04a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002306eeb83de882be7668754decbcb41ee2044f9f0133418d0f9154790bf187826e064da212c026a543b783a5b7d147075fa7e3a87cc81b8d0fded69c46bd354b351fb499f1b496c9aeb609a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024dd381d7c1f2822c4aa783cff254aa0e184f212353b1ecf0ce57eace0cad5724f4005b54f8ef2b6aef3852def208ab719c347312d2ec82ba2b55356004d54eb351fb4b781b496c9a52d71500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017500a7953f3a52b64f89f7f26ee887beb873e863c523b3a0be5ffea35bca624fdd75150fed8e4830e58dbdc5517dab02482bb4a991b92cb4778600d119b06b2851fb4bad1b496c9a0ae87000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c89f6955c67fdfc6d86957d949ab6e3f79e24a74adc70c9cefeb7dc9610182564de94080ae4953240f3330821ce76831c3963fc59bab10a479efeae33c4cdfae51fb4be21b496c9af2f43c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000247c66d117366c5bcd3ab35fd152629e47a514b34273a0079e18fad82735bf2127e975fcb4a458f4438861136a212856f567d17171d5e6f6867fab4ec4cb2f4d951fb4c201b496c9a0c4d6c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e46ac908bc5e4dbf888221952b98cf726c18fa78eef5b7043ac4240796ee961256269838dad8d4efcf849c803a228d958d37c8ce24feb884bb624046840dd5af51fb4caa1b496c9a7c131500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d26266d817158c6988bd6c5e7aae285257cd9370467705316b70fcd25acd3a1a8e44a57104a97043f4c5a0c286f17c8ff455d111f92a50559106c49c74aba7be51fb4e2a1b496c9a4a648c01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e3ed8357ebfdeb6a122ff474a2575dabb72c51d380a3ebdbd032777bd86be9dae034ce7cb6feeaf277fe05f736f6d0e139893650a05060d51830cc7445ade15d51fb4e5c1b496c9aa0861e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015f8203fd990ac4913d3fa4ac137111951a7c0877d081cdb95bab0a9b46c9060b00cf93b20b634e5b8f5f0a0cf3ffbd9436b9556f798fa317769a8efe7b7e831351fb4eeb1b496c9a36156e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e23cc8de939250893286625769c6e2313546b9b2ce640171c7da6ca1cc89f9ba9b6e94c20ac7210c5c331d75be2765aeb888323590fb1441ebf41a44dfddcdcb51fb4f7b1b496c9a51d6fb00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002de5fa73f9672390399aea3b2820eae28a26c7825026984c23799713a45be2ad1a6dca15cfff33f1762b07551b4d0bc3c46cc6ea77b9ee0e72aee70009121561051fb4fe11b496c9afb475000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a67f8ccf9d6323937625e6f17d2bb3e7ffcb27e2a28c17ae1363e5ff8283140cdc8ff7d1b1097278d136dbc9e281d798b5196ad53a48f378e4b74fc18c5e836f51fb513c1b496c9af4915975000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f6d73f24c0df88de2abae776da17f87bff469a069c715336ec9b14548017153081e44cf5e982746990d74e7c82e677d01855ff824efb9d763bdecd5992e6162951fb53291b496c9a52bc0900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002df2322ab86606d0b90408b9f73d38765e157df3160a785d0c842bae1165ab53daf86cfec74bd59ed9d9fd5ccdbd0b76cc567d4a964e2bfc095a2ad5dcf512fa051fb53321b496c9a44da8300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026ae5328b184bf70b61620c0bb066822640b56c64072974b886a044b7dac6e5ed20cd5f23473a5ca7e49f42d05dc81f8c8bed727f8045fb4071e72ad0fd30623451fb534d1b4fbbc782fc56b5000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fcfcbe30914be8ce50843aaebf4f05c29cd534ddb6a24d4d4c8bbc6096a81ea4e6ee0e353e2809476012853a0966aa5c4a049449b35d898e8818a7e4b9ab5f0551fb539c1b4fbbc733453000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000297ca7510273efc50588838d54918c5985ac4fae69114a4cc3b4bfdfbe78787f06ce3aa74bf650373f0cc32fa2508d5da67b98657943528e66330d06f46f19b1051fb53e01b4fbbc786b40900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021267f3fc8f920be74aa98ad406b57f073157351e0b256ec712cbc3bf63ea8cd17dfd390977f5a45d836c9b1c8275156e78b4b38ddbed107da4e2a4c483778c4651fb56cb1b4fbbc7d9f83b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015a7183a6bcfead5dec865efd0b54d59f5fccecdff773bf3666a73f15425dbdaee135ed15a0c9f48d415f3af16bd295d07139c7d64de0fc46df064bfda15fccf351fb56c71b4fbbc7eb3f2f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020c2319af3c770a93aab0aea24cf88c7c5d68341800d2bf54732c42efba94eba06a9fbfb03dc1ff6a200aeac7110d87a530771d3378fb1b6701724a8d41303f4b51fb56ee1b4fbbc771ab3e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002175f70ac8ffdee8f3a3acb2a59d7cbf70439a9820decabad1b3dce6da95a88bfc78a787650a08c72b888a00ad7cd4157e604a52e47cca4e9460433f72590bf1f51fb57331b4fbbc735fed700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f55c4f1c6cfef13ad04aae9e16e322f302a3bb4f2757bbb9b015bbc58d1579f8b6e86dbe9aad69627a7a7ddbd223b6336a50204d8d48dc3c9bb66f798ab0ae2e51fb57761b4fbbc73f35a100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bdcfcd2d4ff26e6c022668fc1b89e23bb3fd840b9a1109f2ff02e3630a8b43b320e0af430e40224199b7163691219b17fb2a18c5a702eee15975d5c318825a6551fb58e31b4fbbc7fe516000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022a6ba28e2664c25aa7366e12c2461e8f04412c5cb29b9ef498cb72eea7d00438830eda933c52a4ae5c35812bf90a03a2ceb6417cb4df3d5f18b3d613f6008a0651fb5a491b4fbbc7fb8a1200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ce0adea980b686fe73dc3a86440be45013c769fd96f7d56b622344d2157d347416828c835cbb0b345666440042aed3e369271168a5b4b744cb124e0c0d705ec551fb5a7c1b4fbbc72740d100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002825665911a86c068d776ddf6d23351b0f20cccf6ded93e94e439d199b7ed17b09fafc8060b762b56695fa5ea62f55c5f6e427308f089b93573ddc1b3a7c36ca251fb5b011b4fbbc7379a1500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002196abd09a0e343dcf49eaea8e18f360ccf1d3057f38216c48e83aaf3adfb891a94725927f7b1ffbc0a3be4877896fd08d766c42cfcdacafac64ad1255764d28651fb5c8b1b4fbbc771f00080000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000019b35e44f08097960a35563ad066bb5bc0d3a6f0cf1577962f04d8cb6aa8f7e261fbe4b54ba09c13b351bd817ef2eb2e5c38a85ff1277e971964fccc2ecdeea1a51fb5cb01b4fbbc79c4f1400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c78f71cb5e245b48be38485ddcc7ef8259c5b3d3bbb5e03b6ef9311997f554ad341f20be98c27185e44c79e94f1703823b45f3485ec3043ed0be5a2b6c7653ab51fb5d571b4fbbc79037e301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bf2467742f7705ff0f3580fc5934d6b45e51a55dd4f9e3aa9d47f2e573891ac92dc7f46280cb7a80dc0fcc5e2318defa61c2854eff2fc96da80783b1c0e9595a51fb5ed61b4fbbc767a47d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023241fbd9d3d1d808f79add29a8df70164ba8bd8e71e541171538e11e17bdaca5fa57578b064aede9f0c918e29cb0d433f93f1e6a91006f15c23245b8fc6b2c3251fb5ed71b4fbbc79dee0180000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016ac8cf99f7197f3d05a240b5d747cee36f707317b4bbac41e8c895418b94048f69c151e2c518f463aa45cd932674900758bfc32559c44b4f1616f5ccbdcb833451fb5eee1b4fbbc7956bef00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002083cfa7aee0edd46bb80b02b9a2048611e09722bcc2ed55f595c47dc8554668ecfa1835b210542ba94bcb681ae6d8d131280ed2f88112e8b5023e50796b542c751fb5f9b1b4fbbc739316a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e1e5eb72158c9d3d13b20db894fb3611fe248987e97aaa97fcbca68f7c97e163a3dae1652c39f39b31e9b6578cc9ef2e7c11967d7036cb7d64f5dad7df9f12f451fb61b81b4fbbc76ba23101000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b717c928e72fe5714dcbacc87c939ae006d77ef31aed5b89ef9313a28b28142658dcb52045728cc693da029195050a9b710a5bf2c7c1379f7d9fcc8de63b19a551fb639f1b4fbbc7fd5ad800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002313f01485c11ad13c1340667029605ab4e6e654f848778f9a32ed5783e1612c87bbcddf41daf7a2ced0f3b7e72885d0784813948c7489b6fcb1ebb3db897e2cc51fb63e41b4fbbc7beb02500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021b39db93677af85a098f29a1698d1bc009f15158c816f8bd4da2f213f257a95a7030d6e1c41af9735549fff6527db993fdec8b3e661b2820995c6f1a4e69949351fb644d1b4fbbc78b7ec400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000213c6b24c833d7be1bf0702e7a1ad86a37496964888f58f2c05e4943f215864fc437cde0c9bc5e97ba070008bfc45810400d75e65f394fb6b74df1368b36c43be51fb64c41b4fbbc7381fbc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020aee9b4ef4db97059a75c387f5dc58fd00c2720855a22e1a9dba03e9e5ed596c45ed5567e097b7d8be2705d6f1cc90b3be20bc2248043115f257d1e2dc3cbd6151fb64dc1b4fbbc7ada6a700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d8fa226b0ddfc4ea9f668acdd837d6a289fdfb42017ce1702890dbed2cea863c9911db08cca654ddea7c18b12ddbf1daecc5b7c2e8396d5cf4cb266b124d564551fb64e41b4fbbc78a1b0e01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000246bcea6538935967869393ac5b2f9e1be2b730f59dc1b5a303d5bb297c97538247a126ea8b615f4051f4a64747718c43ae0219886133abccaf6dc6308f75923751fb65061b4fbbc799f8abea000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ade13d9a88b4465eb3e6c72dcc016ed582b25af65f5411e119c1833f73caf3bc71fc409eb5023444201ac6064ab1f7e5310bf91038876e9c1c0b148e7de36e4a51fb65721b4fbbc7a9ee3f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001239d7d3b1f850a3b13ba270774404bd6c688d6dd9b793bf32a647d0a5424ddb99a62250692ca02e7856c90a67835c6d0b913fc2d89da4609bf3c11f0e3ad577b51fb65551b4fbbc7dacd0700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000251952d8ab5747e6940ddeb4b89dcdea54276d546373d5d452585b6546a444d9792fbea4a1f7cf326af59f3a936bd92a7f11bfe525337da66d482aa6d3e20013451fb658a1b4fbbc79ff3a201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000115a8840372ac90cb74ec5d8e3475818f7eb8312c50355d5706b3605807e91deeae13bd1cc272324bc3d3bf7cac308e128dae4b7721926dc23915f1392687885651fb65de1b4fbbc78f854d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f8dd0b8f6510579d0728a3a47e0d20bf960b31de2742e057ee479f65645757809a7f5cef6de1ac72df81c67399a6d884fa200f2f1ecd77bd77672213065464b651fb66b21b4fbbc72bb3a700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028d8e9e84770f21455ff7cb7cf865dd069bf7e7830fe9a6122bd04ce00e31482198762cc3c93e5717fdf035daec9ca4d31743ffea81f7cd696a9a635b035516d051fb66b71b4fbbc7ce7d4000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021f7dc6241f689bd3b6a8295f25612bef36b9b95a0119c50c006eea3271f0e018b336ecc1ae749b0c016ba923a26ef84619fbda15299e85d04498416ab5e7c33451fb66c21b4fbbc77e960700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b38d116f53e3178f775d86716eacfc1d0c0874c7170edf5915b5cf871488510143896394c998201606ff8738e0d830f4e9bcf1c98c88e186625fd4161bb2a57451fb67de1b4fbbc727450600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e04dc1b75b84b4be14ef25b0ff12a71a8ef33cf9d1bd0cb881c7d214e0ce920c7d4b9bc14edf6f8c35b4452d725ed1586241ecf769e6100c55dcf29cf3e8a2f251fb68101b4fbbc74aa1d300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000137ca3b3ae4140031d9cdac8c82112f34a4fa2b5264a1dfe06cd476c88e96cef964e0c34d9f41320a7fec5b7eba223116de1306c9cc4df9ca53ae6845d0469d4351fb69401b4fbbc76e0a9600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f34206a6c6199b11a93fa80afbc9016f6bbf85c3b3c4bef2da350b7f54cf128ecadabbedbffea58e9e2295be0a9061ccc025f8066ca3551be24a9f4732a82bdc51fb69671b4fbbc7626a0000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027515e4a3b4e094c8e31309e025df890962afefed76d0c52aed178b7d5065fdd69febbf734faf82053e33c94a41d9786769aed639ac38e3d52e64931713a9c80c51fb69db1b4fbbc72b84c200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000294b0e1b7e50632f5ca9d3d186163b2a06d99f324e2c25084332d0ea01bf83c87b929c6b901e826e3ca3741b3d754ebedc186f26487ea0afacb49223058dfb6b451fb6b821b4fbbc704e90f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d5b9e89d22da8fa73e074155de1bef1d62565a6ba269fb1ce801892f0435bf8333677d97edd480d4add4f9668088066bb54285665435f20171eb05f55f06b33151fb6ba41b4fbbc79f9ab100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013ee76137b6b9cdb3028b9f8e095e287fc1a3a995f42459fb06b88ca87a7a4965568fccd5728d9ffdeda3af2ca8dc212ebd1857bba279eb8d1c32c25dd4fea56251fb6bc61b4fbbc7f5580901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ea834bd7ebec08a7586785b56ad61d820853512e861d24c3315d2a769b4df57ab2d893b37e3c9ae761fc98a5ba8b034c44ebaa7fdd89af3d5072579b60f7813751fb6c0e1b4fbbc7df2bbf01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001cc7378320d3cb800e9965094ce1cb9d24c7ab673e86b431461bb445738968ae692c0dcaef436eb61a9570a62e8f998159e069f773a905599e328dcf4414b46ce51fb6c471b4fbbc70214dc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ea5d5560f307ba568f88e1e1d0b3beb1cbcf3316c3abd41f56760b1ab0d1b7247dffc33c5c31c0beb2670ae668e1eedac983d80cca5f323cc5c7e0158d9eb52651fb6dda1b4fbbc7a514bb00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022ad60ccbb074258be51d52c7db3874b8fc49c01134ea463f827d5a59d77a1e3f03855810235227baed13704a4a1ba7c6f3bf40fbb165d63300206143f58f71e851fb6e4f1b4fbbc7ab085901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000235d84f0bb6774840970c88d43b820bdb7d997f8cdd52924fa3cca9e72222fead460c5da7ab2e61ac3491f7598f7fb7b50997c841a2607bcc19f13458de12236751fb6ebc1b4fbbc780dcc300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000219a2b02a81ac08ce6ffc17ed9dccb07fd277dfe1ceff6d2711a3911e6c7a3f46e158d5c35342e09466b514ac7afa39b7cbfc0eb6cdce1c5cbfe3d5dad2b2fd4a51fb702e1b4fbbc72e152c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000285ddda6c6dccf9df7e7a0c0f34fd3cde7f3961ff0f6113448633915ca0e17e5b432cdee06c80df2b5ff6a905b7205b6c2c60a5e83693c4ba27845664487eda1051fb703f1b4fbbc79d157500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e7ea993a5ee66da735c48accf34d2c49431131dfc9deb84c76e1ea1af8556aecc1770588544a2cb5a03c073b44fe051cb55026b583df02f1dc6d8d7efca0fffa51fb706b1b4fbbc702f60000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000174976152ef2621a922c485e9fe40922e9a58f8edbb43c227ef557d253f02feaee21c656c162fc5643ce3da9bdf392e28cf9a50af57508a932c2d48be2792b2d851fb70ee1b4fbbc78251f800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000208d7b446d7f4a77bdbb48c78b1bb9256fa91571bd858c96c70fc6d6d39a12118ca098b7c86fc09142b66d49cc73a0b2022042505872350e2600ae89baaa026bb51fb71c81b4fbbc745464e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d8613b623599e44988f5edefc315ba60b9201bbf0f337b7f134f01746c75468df1ce6b9ebef5f86d4db9569d6c9fc58f9e567861e2ad40d956b4a0e2c3a8672451fb72101b4fbbc70511c901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002427d99a64de7521bcefce9209cc39ac115ae680f2e7b7cc59c711a427f8ce63781605f92521d691dfe3d302ad6734c7faac43137dcf66a0d244442b5bf6a086f51fb72ad1b4fbbc793865800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029f0d7ff18e7b82e3ef6ff8d0080510e2e7c4879f7e97c93220bc310846a774ab62f5c386deb1dd71e9b1451bddfe470d98ed1dee0974c57cd11d63bf5645624a51fb72b41b4fbbc74302ac2a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e3ab986b11084b832f10bac3c96657b8b1b7555ae068e4f3fe5b8237213afc428c4abe69d7d316da9cba53091a1dc2292b3a0bbf1c11652d039d7361251b4ab051fb73ad1b4fbbc726d00600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b343602a507faccfa9f0cd794d0792b11998845411e1753e7851924037a09ae57d0f85baf082928276abf1950ea083260a4e0bd59d8245573a1b683a99294ad951fb74731b4fbbc70000cdb3000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026536f92962d806cf365b7ef19e12b844f45d964f1d7791d746da82bc20819ec77065acc44eb247595f3f9719f81b284fcccc13ff74b1aeb68119163a47e3a7f051fb74a51b4fbbc7b0947400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d1fdf2d1ffe454f6c00d89df2e5ea9f21529b328995208e07f282771b945219c190cc375e9f8fb8412882d32dc51294ecfac0e3433c23fa297898f8e38acfd5d51fb74a71b4fbbc7b3d707f0000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024229b6f20adc0d2119df9ffbe84a153ed5515a949bc504c96c8be725786e98dce2ec763b0a0f46e05bc3b8e350ce8c92cdcd3d6ebf75ca1b46d065975f53a95451fb74f61b4fbbc7eb716c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eef0165fd02c34bee80c51dac8342bc967937fc56a0b5bf6830eaec9526ebf4cf7bc2ef200b050d84fd9dfc70475f1c70c63377eb029d589ee64a4778864f43051fb75091b4fbbc786659000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023cde4026b7d9dbfa793b570394f73bc373d093469e941797f2f838c4b425616ded6ab455c0185e096eaa759c72cde5a57d15f85f79d4174bdbf8f693dd450fb151fb76031b4fbbc7336fc300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e3847c6717376ac1e171b2503741c7de0bb7a2b16949f20475908b07f34861633a2b19c0882730c74a955dc6e7fe59e8c1a99b0e24c8cf7e8f9c42c76b96789051fb76171b4fbbc7c5f55700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b10884a56d6d05d8eab417674c4299d953cea2d680cc61c94b6f2c0e97badbb47ad19c41f9690f4d52d1e848fe959e3a64ad9aef86fc0ad5d056e53e7fe269a251fb76f51b4fbbc78f673b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b3770b8ffa50c08c2b9a5f92f56a28833a6849098c748bb6fdcb6d6384f29e67817f604d07deed0bd6dd83cd646240c2ace9c8129a67bf1f97e71cde6e7e42e751fb77341b4fbbc7124e8601000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000259d8b9dfb3b38a7fe843371fe80d3098a74fffd4bbb1caa10d3babf07afff943756c8052bc1f2bd9925e5ac2d568e3d6660483eb50c1da47535adb03f18fa5a751fb779b1b4fbbc705a8a601000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024041ae098f90057ff81142c9461e8584765ba51d60971ad95acd743853e43a3848bf054b1eb85e3695c40b683312246f2eeef3c1824afb7f17fc70eb64174d0051fb78861b4fbbc7df1e1e01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013dbcb7bbdd9645a44fd8dd299be684787e492b485472da98d42dd3d450ffd625d1a830320dd533f5d2d0a58818af706447a7a67a4ea5ceb7ab4071cc63848d8351fb78d31b4fbbc7d1346500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025977467a90b3b9cef504c686183a8a656169525f1ff55045ec47e081c5c4178cbe39f9189456aa00a5c01403cec83039425f00fab2051c603c2b984ea73ab81d51fb79011b4fbbc76b260800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bd8ffdc53367faffb8d672e23f92445a0bdddaa945032511958557fb785f67befec1f326c38c1638123c4fe4365b2eadc2a9aad6640c3cc74dcae531a4e1bac151fb79371b4fbbc7a50c1d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002614fd662ecb5e6095a96fa68bcbb5149579218128a3ee3a9af6b2a666d6d413c81f452865a4463c35717736a0fd1abd8eddcae99cf3d714cd5bee76bd88fd78b51fb79ad1b4fbbc75a6b5900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023eec953da9e9481dd095df57f6aab7e7a7639574483d5bbda7f6202bdac4f3ed1ebf4c9cbc66d2a34100d8e2fc625539c1f27b6c47aca6f584bc1db35d0a6b2551fb79c21b4fbbc7cfc10a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002296fbb0f12b0a4b786d018b0f692ccc67d985db3341eabd8a2a68ab60cd2e49694151e302ca6027edb805d06c3a80270ea0eea258349b76ab6f422d3d00230bf51fb79e21b4fbbc75c536c01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002391faa79d8a94ab08c05cbe3c502f40cbdf1bcff431358e67ecc22d949217935df21da1c92935e1adaf91aea77a5e3a6dc2c09d74a55bf0f7f5b640c88d6a16851fb79f31b4fbbc753440200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b95e7525587d3f3374d6fad77e6efad66fb81d9efccf8ab9bab408599010e8b01de87b3a66102cacc3e64ab9d7cf79938494c186812ad7d91c955d77f2f29ad851fb7a461b4fbbc7a3e3e101000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001b3ee290a9fb178ce4e97c15c1055f12a0bdc71cad28cfde2d36a9e2dcef5f61da19ec4f3d5ca4e8931cc8ffb00d2aa95eab04d69aee14e038a17809c09ac0aa051fb7a9d1b4fbbc781486869000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e1718ad03d5ef8af4a68cddd0c43b206cbf6125c6ee42231286946003b8b4b64e2b96a0610744821cec36936853842be52da034ee984f6fa1248ac6839d2883651fb7aac1b4fbbc7e0d78700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021772d433ef48449bcd6c9eb0772075b5ed921db373bf7515c01a1b0328ef6dac783d6ae2ec603fe7428f25e6e6fc7bf66c7d823ff65f2706ca4b5ac8ed2fa03651fb7af51b4fbbc796bc3e01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001be2090798ee404c57dd0955811a8c47e5a0d0229d268c79f3359baaa75ebc32a3b9a791299432f0139a49e7d626b95761b063f597d07129abb1d6e2a21ffc56251fb7c311b4fbbc7f7570300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d63da5c56ab5023eb2fb15e944f0e1388ea367035869f38d809e1193bd47486361a7151ab13bcf807b2a3070cb732e56821b24a77a343238cd1d29967ad3678f51fb7ce91b4fbbc788c05800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025c2d684bbcf73966ddad73157822352f5716c0852156668e2427b461222008b6cfc39249fd5e0f891a0f68774ea106fdda47c6fe6f998e94816edd5463eeee8151fb7cfc1b4fbbc70b515400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024f00d1af0936990812872eac1834f5ff35b43e63cb58a3b1e7a7825258d12ffdb1815228aaaa7b520152a42dbecff07d1899730f913c68afa3e7b2487b84686551fb7d0c1b4fbbc750827300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025cd8fc0c618be31c2c2f6b8cc61f0027410940fd44a72f5c16bd395af57b9e8a0bdbb89f2090f60bb791d55a0d4c6529084710d836f24a619d87509e80ccaec551fb7e721b4fbbc7f3949f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000248ecfcf4fbd7ee274ef87837c96b82979045fd20c90072bec043a9a049265890c1e7c6a3652e39a7d9e8171c1813ded7d7720d4719705e92e526e51d302d909851fb7ee71b4fbbc79f738e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fb85642f2fcae0dea56ba0cbafeb4cddefdba348072649c4b0249f706207ede46de69eb940505d1e980f97538018b8d59a2967a0216a350100d0b90244d6a70051fb7f2b1b4fbbc777d92500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023911c311880fc07a9c4b92bba85fcb1334f177f680d6a9b4280cb9e536eab5d2dcefeefae6b85d8185d208fd9c7c8ca2b8b66d28d6ba5f9e1b78ae3e75fd1c9551fb80c81b4fbbc722ae0700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021555df271be6ccd336fee257ca6b0ddd0fcc6fc38c7e02f8764b49fdb2aedccb0aa79f7e9486c00f59a1362283f3a4580cca37145d54e5355caaed7a6c27765351fb80d51b4fbbc778d78300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000019167f923ff7efcae3b89a3e7d5eb6f436ff3292bdae1ad7e57dc76efe12cd0c280ba8fcd7277fcb93f36ef374a8b9c392b810796d5990338bebe73dd3882812d51fb815e1b4fbbc7bf273200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000296e48f7bd83d8c028ec5a180841a90333d8d4ee1c027345a65aa407a7d13cd1939bd715a53d820f557f66c2da2a49720dd728091b68dd62625f776f41deee02b51fb81e01b4fbbc7b9610100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ff81fbd1bb3dd1e622e7c523a280d7daec64814c2f9e627c2c35319685ef7c01338d4e38088187f3fc4071af6d498517aae2abb83cf09f30a6af8c7a325e09ac51fb82bd1b4fbbc76d1c8500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021aa87c1fb78a550e6e6b2abfba3922e9c7d880dbad6844891adb7094b03fd765218dbde8500fca75146f34b9d5be766c950736353bbcd1e76f7c5e9a3cf409be51fb833e1b4fbbc7cf971700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029d351375cba038cacff1dc8bbac87dfcab8746e00e270a36c352c8e7348730d36d1b61bef6e97de0b4b64e75ea11b69c9e0aaa67d33b37392e11a59850a79ff751fb836c1b4fbbc706ac4600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015ee3737ebd283d57af1cd660a414fce24285142da504e2f66b1a145376d6b04c4b8474713bb8e5000d3ce8c9edee7a4604384203d0862058138a675a72f4707551fb83661b4fbbc715cc2500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cb8ad7d9f4c5eff8169bf9842bccb7dc24863d017b7385efc0808fa5ac36e109266e9a7420fa507aa4fc26bf3902aec1d5583550947fb264cd4203352291963051fb83c71b4fbbc72ed14300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ac8a0c0d88e4e9e0a8df644bbf949f49d056eded9676dc9c4c391426c1fb8f31f5662b8e734a1a3b4ee411e26f38913985db6c454d394d4bcacf8ee6ec1fd8ea51fb844a1b4fbbc799482600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b1cc6d7d1d41d2d38dd1035c89107b4b0ba0185c0abe0994b10bb3c24bb381346d3baf173979213f1df61c1d023aa956b88c08a81a4f23e18696693d8e313e0b51fb84841b4fbbc776e40400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000127388ab3d51abad9278b7faff61f8a293ffb928c4a8785abb72a80ec5116b731e107da916c2d34e388b3a4c837c03364ddff84b543e1caf1424f76088a1dc2a451fb84a11b4fbbc754e71201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b2844aab382035c5febc81cbecbeca1a985eb4bd7ed57c45ae78ddc497bfb5c168cf96afae451d4cd3b534a8ecd27482f3a722254669d64d06f93c301150c36451fb84fa1b4fbbc7f479cd00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026db03cd8000f75f69be33a35ea6999133ccff2ba1a30be8c0ea65bcfd02b6690d13e56ad88b15a74eb527a77be6e6fa1f955bc93038cae7500813b82000686a751fb85e51b4fbbc777795900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000214b1dc87ab9ee55f6cd09945cebf88bd8441871e72e3cff48644c7a0a268031dcbc5475458ef21ae4e65a5e54236fe140444db59eee93faf6ac18664c79a0c0051fb86681b4fbbc7a4cea800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bab34f95dc0e9f2b097e3d24ad04489a4bccd916ef14755c27d84445344a1cf888953755d13545c842c6a22416cd6e78bccb2b113f8b99510b0b22e55ff382ff51fb87321b4fbbc70d555e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f8cd44c86647fae19255f06f32f88a6687557ebd43337dfc57216e6dae2ca33b0c46678f3b6a5899bcbc9484bc83b5265cfba7257c0e64026e5785f3d127a11851fb87471b4fbbc7b0d60300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022d0cbf04a676c67f98b543b3ababb18eef895f1c5c773de6b2197666ff8055906c079cfb16f92dc421d191c3ab7f9f89c43a47c2de8654225331f39c6cf9893e51fb896f1b4fbbc74549a000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fea2155835de11e7bac60b4929fe7e798599f4a2926bb487a3918e2c6bd91e8a64d3815f19dd0fe4fd04babe15e8b567c05c1bb420dc8a0de776d2eeb717ea7651fb89bf1b4fbbc7fba2b800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000222c290c72238d664a513d82e37dfa10feaa11167c423cd75b8938af389bd8fd2ea42c9400f7a49a47dca4e8bc286d59011df4f5819f989717acb90effab1348a51fb8a171b4fbbc7fa847000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029048521cc940b5c4bde27c84488662aca8d0510890e8a9d2269c53356c935ba1136a13bd3cc803c52627f28e40382950e81a26aca6211831124e3180fc70d3ab51fb8a951b4fbbc753121300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016673b021e90c7bc0b9ea51ce5e17914bfe452543e2a26c27dbaa25cb6670380ec139c2b4ae95b32a2a064a7171df2e5a0483c6a1618bebc62cc784e7c85c401351fb8a731b4fbbc748b00180000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d6a15d6cffc825544476675884d28075b50a0dc50fdb6325403193ffb862b5927c9a50e3c6cc2a8c85b68bd7adf399fb1c523a60b24b3f0d47c53389a9925a0d51fb8aa91b4fbbc7b3ec7600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000223d790872088e1027779379c3d763d877aa841f4eda66e679ca417a9bc5bb064963c4fa8094f4ac65aa2b674006d0c51960631ec2c6cb35faa066e0a3db320ee51fb8b2b1b4fbbc737b21100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fa5f6482bbe1b98beb9e6dcafcfe49779f7dac3f183f9a23272d94fa62a788649762cddb834e7ded9203c384f868897591dbdbe6a90a238ce01d64a3e1079f0251fb8b181b4fbbc765274700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000205ca9950a567a39f976310593934adccef972d5a1e4061fac29dd22deb01045fd70c3b12c5c1a3090ce760c3decb4ac566cbaf794252ad1acbfd29bb951706e951fb8b941b4fbbc7ed927f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ac3793ac4b6adb931c67bb8b607e79d7a0402632a8f62cf2e91efb48e268496287bb9a80bf425f5a3d0faf5e302c5223bdcebc027470c415a90b1740fece87ad51fb8bac1b4fbbc753e22601000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001aed77879f95eaf13c4e2541a0df50f0cd94ffc3a47d0f0e7efde3647e58ff94471eb59ff1703d4b14035990b4afd845a5a03c37b5f787798e3a86b4d621172d551fb8bf11b4fbbc76d3c1200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015296014f87a38774f1d80ddaaab5cf45781b42808b5a5330b86662991519f14b6510249e1d4e78de8a3dfdce881b4464d2d5a137286c86d3bc28855bbdd1b0d451fb8d0f1b4fbbc729f83000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022d4955ebae1546c3f580380a2a0940004f8cf2c898a9f2ef5fcd8ce9b650fe7258fb49fb197714c278a6c5181ace5da981615c9c35ac88ff76f89f477745141351fb8d331b4fbbc70c816100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c13a0e4cec433e63f3576f35a97a339a8c8e8fac7f4f99156add6f9bea6a570e535ef28cab950e4fd206e2eaee05a52991ee8e4a3dd17606b720d2bf16d49b8251fb8dff1b4fbbc775712600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028e420864f4521836312bd89850d9bb414b2a1134c28a621a196544c92b0d03fcc87a262a81faeadeffe97424af445223bc8628268ee06d08d7a6edffa4fb2b7451fb8e1f1b4fbbc75028d100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017bf458222d532749780199ddf96930a3b5e6606e1913fa1c4cf9df167cbfa099d297e0e896c550ba1be8d73159e86f2ab98ce6d070eb465c21bb8fe9888a5ef951fb8e401b4fbbc725751000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002596baf880f0393f7b49c17472b0eb039425925b7b1f529c53528a735cc494a9a8b86d51cdd621115048f90720335f9b8ca0179d50dc0793548063c05aa850a8e51fb8e7b1b4fbbc7219d1100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ddbb07315423d2a9b1ba40fbb5deb670acb3a33f0c5ab75895d63ce7169deef9a498b7702b57f598747425339d20807807a305f4179c55b85a1e9aa939c1719f51fb8eaa1b4fbbc7db000100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015587de54e3ea4e9e52fc3cfe1e056ffe1186fba881a29626f76f6e507ffef1443a286ba919334e377dfc1b7f6241259e05c16a060c5369ef4a4db34445f8741051fb8f781b4fbbc732141500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000126a1168c5e95e899b5e66ae10eed2f06e590a38f349708f4d7eb6282fa82075a898e0f68d2ff62b41d0998d8bf7a2f2d6fe12c42df579c0bf13720081439867051fb909d1b4fbbc7c0100d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013799da78f1819a1256d0522a73a7e20754528c1c07d59623502e697488054d819ea53b19682d46a68889e725f160fd66a00ab87cc8d98f0247b9a05fad5a14d851fb90ab1b4fbbc700016fbb000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000202a7970e190475cc54e63896acec08e23cd4b93246f546bc28c138b779120e4d4005c5d927c597c9e299bb4c572cd28acaffc84f26d57d07f18b4788f1c5b5e251fb912c1b4fbbc70ba78d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002105ad4d32c0997d2a7a83026f2bf74f2ed3e60500c29c95e7f9466ba458450fd5ca377707c2d9f78cc9f7d3173e4fa7206d2a95a1cf98d76b5f60c3237ee7bc651fb919e1b4fbbc78874b700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001679a2a0e16761db1db40230d23fd9d77da3be40966190b25aa838e7e6f7bf52aea1d4ea8151f3a9f19d964a43f3e5eb3eb1314d5e05072e389e88b9562acffbc51fb93811b4fbbc73f7e2000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022174e28424277fd0bb9e1eb3837ffd8103d953f4d1dfcbfdb12d9a373f49ec3c99724e39610f7a90adc53afbd87fe51c9a2a2e22259c2a8b734f427f95c94eda51fb93e31b4fbbc729ad9900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017daafa6ab73e8918b6b14439912f7ad8af3c45c81633b0c1dd38a4eb16b73dd8ec71b574ec6455f4f5929b73c2221ab3d6c0b99d227b49a1242a0ddbaf50088851fb95131b4fbbc747c36b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002132c3a5c86f4fde36c3a0e3ead29b3258c399aad846f4c4f9408fb09a4e151e3ae88f27ab28a6c6bffa9b9a5c3ab157c3e360d3ea4327e5bd42b3e5a2d01f31c51fb95d21b4fbbc7c005b300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002016897b4b0a60d7dbae8204788e4ccbab940f62ca2b71e309dc5c6ffa80e560ad93e0c34bf962b1967dc06504350fca5d4fb71656cf3126d3d7a3c65611ba8be51fb96a31b4fbbc7649f2700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015e566f36e7ea9a780dd52b02fdce9c80c674c4e96ff60735c1865930c029ca94258992f7fa3cae768a2be503dd65ed222b0a8a58f654033b51f530f546c9ea2a51fb96bb1b4fbbc7880f6d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cd3e0b85b8a02a722b03ab2146d720ab812894b315019ef9cc025993af01d861e174a7b8e028143a4e4a256b18da970303a47d5587fe8a683258e9d97639428151fb97761b4fbbc7a70d3c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017e7262ffe76b2b5c071eb946db059c1c994820af1cfef25362d39afa5198237bafc18a1f246c1c4e8f2d29b48eade6af12658159072d055ad5579cd4ecef4a2e51fb97b11b4fbbc789a30901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025619a502ba3dc33240645189d34e52219fcd0c6c09c09df28e602950280349d118663e1e05ba4ba4a07c8fb8f938fe3ed65f3006dde34eac97c60b39f53b378251fb98161b4fbbc7e0b15900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c77ad562b3af04984a0629acd8a33b2f1ead456ec65822a76bed507ec70bb0bbcc39f7f75d1dfbea6a525281da0e6a07979ac520cbe01c68f5ca4f805e86243a51fb99241b4fbbc7abe72300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023d96bf7b4b7b9accf32e2c8293cf71308a1f55bf2426a82a2f5655950441fa9a4d2a6785b8e48ff0106634d180a406ffe1920336266a78d0561402be89f6a02c51fb99301b4fbbc720050c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021301b6bdb22b8dc01a00e3386653eeb0840ae875f5cea6a1cb19239c82a1cfe04c39e7737d1ff350a9ef48d41115faa347f3f5a0acbf2fb564c01ae3d37fdfb551fb99ea1b4fbbc7dd0e4600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022c378c67d5388fc725dff609e0b9bb9fb346f2b34457aec956b6ce8cfb36915a25a8043f2ebe72c104e19ea8da6f61ae46db760dae75ebfdb6a99e346c9591c851fb9b131b4fbbc73e3b4200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010b499fdf38d34602c1ab35c103485e112794f9f035a78bb5507e0213232c0917afd4bf8deb01cdbc5b1b9b8ad4ffb60c44bec33b3fd4e2ed15a9ffcb9c527f4a51fb9b441b4fbbc7a0229700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022ddd2abb10d7117dfc05dc14e9e4c011cac0205d3b53f772a027c6032cdf4b877cdd1dfa56b64b210d201e9e142ddd0e5625c5e78e2f9745fc410a996a18d55251fb9bfe1b4fbbc70d82cc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002317192c8712e2c8dcee534a50b99143718059cbdd8eb73ade9a23a306432d48ef69c48ad3dd46859343647464d1337094cb1ea5dc682469416ce6f03c193281b51fb9c261b4fbbc72f439600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000113c974c62ba21cf8922bfca9cf5eb5272f40ea03ab9cc349a7a41451156820493f2b46f3c179eed466e55503fbb2e7f3c4c69953f10c62e293e7723cc3dfcae251fb9c2a1b4fbbc7035e2f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f8fe2e5668bd0ed17dcf16ef6bc8ce9807c30ed6412161412fa30cfff02b9652a084812dcf9db4f44797626392f784645b5046959ddd62b3dbeea628724c209b51fb9e571b4fbbc7464d2400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cb03835afe388f07b677b3235f0e56917416be8d84cb5c73d17abbe1d92893795831a8ba4c4de236f565ffcabe44dc23da869c3f267ff3002b33e0b54db4100e51fb9ef81b4fbbc799a50c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001cc791e8194159128f16c5acc49511348e97407cedaf279ae1ba0453e508d8c75abe7e0dc601b4434e0fc721ccfc26553e97e59c2d25d975e0ed5408c37d93b3251fb9f411b4fbbc75cd86300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b0b5595efdf93dfcf72ee12cdf3cd116be49642e9930590f0ec26d6937491bf3893b869dc7a5cf19f70a9cd7e8e71678dba085ee213a79ffe77f3f341259051951fba04c1b4fbbc791ea0700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c3cc2db8952764226a100b513682831bc60efc3d7815c9c64cde0b4e486ec496a2a2cbf5549714ab04b4c3d4acbed524351c115f0c4dd147d3364fdb142631f551fba0a41b4fbbc79b8c3201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d51fbfe7fff6da862f6ee5ce541a2bd1ae5796db6eb2669f69107c311a83d86d698fc64e7fb15eda80ccbfd7bf464266da813e53e1210d382df6a1b71e453b8a51fba11b1b4fbbc771c14a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026a9c9514d0f16c0fdf3762ff72dfbc79aa4204175435c5deb5f1666b2b5515eabcc9233142f95dacf839193f87371fc8a5cb6e69b26588043b156cb6cc4fc9e851fba2641b4fbbc70609ad0a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a1d10899bebf869cf332b2e9d1252ef1a40046a1f988a18fde947234e01eee8ff49d59f62b4da14369244fea85db39edccf32ea8dfb5a520eb979774de5e1f9951fba27e1b4fbbc7f4deac6a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014d9a5ca9e8737ebc4c4428b7232cc35211c22ee322e7b496975593c4a4924cd4ceaf6fc2216fb40d9b76b6499ef472bd0797ea1a4f8dca73796aec5a11caebb751fba2951b4fbbc766747f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f7f867aea2bdbfb83bf7bc012dec43a65cecdb4ac538762b656a98345532b988e073d125c61fe6c536f6d00ab759a2294b5919d839ce6072679fac5f88f99f5f51fba2ab1b4fbbc729560080000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000165a2cca5d24881dcfe1472482f728d29bb8831873bd626a835608fce2323c19c2f72b0fb4e24ff87eaf12b6a4a5eafa6662c2480219f17a47bac8d6430ed9eb351fba3121b4fbbc7c0047c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f54489cb0aa6aa26ab377f49179dd9ce5179d5d7d0ae698dc35057ab51a2b71136c8e4937e3e693c946acf657fd400474562a30747d54e2e259600cbb759e07751fba3431b4fbbc726199b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e7756d613737435cea14e3100b272f292d852548c7735113ae4196051268d81a3f421441f965d784c4ea073fce903e778be373fd4b68583b022a1ae5ef76aa9351fba5121b4fbbc7c3abdf01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cefdecc8409b839bf9b1e11c456c63fdfe40d80924addae8a2d9854e67b84ce8b2ec55ecc605ca37eeefc2f8925e7edb389ac3d113ba276e04d7a6196464461b51fba56a1b4fbbc768d84f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b5a6cd27ab80f620870ad7c41fd1c46a5f64648fd0a99b4b787130515cb1d7a314f2d90ea724600a9e8dec38105a63ce5127ae251aad69534fe224a81a08d65c51fba5851b4fbbc777e14d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002daa63f5e118c02986771b9395f08f257121e713a639d23372e344ca0965c5518153a9d402c4777d506bc72810fbb16d3465c84d6ff49e69ee551b133e26f88f651fba7431b4fbbc73f075600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023e6edb1c4bbf431865522dc0024713d7bcd6f57fc4736cd6d70763d945ada561cf63a2fcce6354eff699dd7928463814bfd8ae96f4a9b8cde976fb15ec01b62451fba7931b4fbbc7e1836100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002644508355c52dd62e20fcfbe3e02234943066d39953bf4b7a2607aac0f33d5fdc87650cd5324ac6d1b98f03254379aafe4234d8ff4d940dd567d96a4e4a82cb051fba8351b4fbbc7a3de2a02000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eb77dbafc6ac8aefe63b85b61a68434047659c4ae3d080915a2e5f067622f0aee22327fd59b78762a1f21d522404d8efae4d54b284e76faef64f3773b9e80ee451fba8ab1b4fbbc7608fdd00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014c35ccd533c89c32f92aaf0d8ca49f79c0238c8a8bf7fcbbcbb28b7287698f60c9a74faa894e500879da3db7d53072598e333aea1cb2e76659a73ca1019e29cb51fba90b1b4fbbc7935fe100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021e281de2f9005c7251b6f8727fc13048e2a7ee71f4dc8dfc210b5b7abccf2c333413e98dcdecca000576d56bc19e2bea8637d05e93b308c5ffc39fee84e8022751fbaa561b4fbbc7ae440000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016eeb59bbce58efc4535c95fa20f162e896440c2b656033fdf308823ef7c31096749e758055219df955272c8f9dd58d9ff48c2e69ce7848c4eb9f884450b712ec51fbaa801b4fbbc7feea3900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a2bb8d263506bd21a04a353cdfd106eefe5ce5ab337f0482a73e6226065064f4afc4a0fa63d8bf8a427e24909214c80e71af062136e49a8fb5e8e44a03c6a69251fbaac21b4fbbc7470d8200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002472b364b1951106ea7abff0dc80411e7ae2fff0faa53b0f58836ea2d5af8603cac3de9a9c2acc59beb28ae556f37ca415b609f36be20a48cec7e29a5ef92bbd851fbacda1b4fbbc7f6dd5b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029d8bab2c0daf0f0e21762e216e248fe045a8be51e1af7c9f863af5d6a4b2ee94a4cbbd0956ee89e5386bcfd678584d6e9ea5a314737f64771d10da131e0419c551fbae681b4fbbc7d6633700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001693f6af53253f1b74af2730431e8abc79a42b7cb17f58b4977311e90a54e4ceaba153d2c21f02c3055b0ba086606d0b4e96f847ca7c9fbe0f768ba068e7fd47b51fbaeb21b4fbbc787b47701000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001cb3b7554dff8dfcf702726a1b31f4de6f957785592c4b1df2d9ff9425a72ac808d1313578e32fcbed24449a525494a4b63b2753c46ff6ed75c246128ca61da1151fbaee21b4fbbc7f7bfd500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000257e8ad950e8cbd9d7e833a63a309d4897b63d36d9f54b000351867dd69e6ab337de10a00d4a6b98a4203a3f56196e2cdcab30b70b307f6a860e31480b8d4d47b51fbaf1b1b4fbbc7dcc7c500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d99b881b382ee9331691994ae571a7b57636475aa65a271b25fb703ee494559e5f25ca8148aded7bd0d76877e8fde91f225c6321d42e84485b880e12d9fb9e4851fbafa21b4fbbc7a4482901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002636bf94042400f2c60f00ebc8663990462dc3dd9aededda4c94af6acbbf9194f70a831cd07186345e4455eb2d84c2fd6111faa53556b451960f338ede6c3295e51fbb00c1b4fbbc7cb7fac2a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ebc3149627bb47b02ffa0c5f31c8ee0ac5d05fe02f6ee6212c065d73138d28234da68c8947a19ee022864ef5f51147cf04c20135290fc50634489502eed1420751fbb0661b4fbbc711c7d500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bc1a8b657c371d5b12a9cc750bd504f0e1380b3e2fba781af8732b7e5ae1195dc8d57f72f0f1c0b4a10a951269097c6a2c147b18a50e4970ca1b775b51ce55c551fbb11a1b4fbbc759c96200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000270bf0eff445b5d3c77506f671872e5eebd130ef5417f5b439431c6c1f17eff647e4bad422699e0e4946a13389c24cc9cd7fd63c70e90dbc77f30ba72ca210fff51fbb1411b4fbbc70f8c00a0000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026f92002be2781c214a970344d4738018a7e176134e20e27f54622b32e9b5f622de483ecc4fe8b4e5aad785fbfc78a8da667621c1897624a3b207ce63d7f49a0e51fbb1671b4fbbc738820800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002da84d0f897ddba0f0691d5a9efd20a8bd981ccf57dc150aa58f0ebfbd1579e0a93b4f2396388dd071ab8f6fdecb69d566c5e329c60ceda60ca4abf7daf19335a51fbb2561b4fbbc75f350580000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001446ec8bba58bc3ebed03135e5d375055a1f82e7adfbf26b9eee2f0237b75a4473aad53846ccbe0d7f16266bb4ba80a33b1ac3940cf701935c6de4b4aa81ab4ac51fbb2c11b4fbbc7d0c72a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029580abd887cb6a6f0e2dc83f1a06716a54b22b8225356cb51d7c9bb306e7acc52357bb838d95f15d7c89c0a777c0ad8571d8e557992b85a13343f6695278541451fbb3731b4fbbc7f7468600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f9f4ba75fda4d4583e988c2c1fa88fdcfba8e7e5405ed8f8b76f89a4ab55c19986420b04ddbc95e0e00d5579ad2278bfedbfcfd351e812fe7f4aa766fcbc38fe51fbb3d41b4fbbc757aa2000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026d5bf4caeb812b7670464c064805bd97477cf12dbc83085f7365b4926423b27cc1d58f3b73ab6b8216eabe15377c9f14d6eebdbbe9431c0f30ee99ade4792a4351fbb3bf1b4fbbc716a557b5000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001b89794a07bb1da747b06514dda1adb1fca3fc1e15daedfd2181b75b3d0714e0d32f6832734afb063fa754521bd78f4b08f9b9db5cc9299c0d894a57540d4f72251fbb4641b4fbbc755090f20000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000018e19ee9503020ce65dc86f7d2130e6179893ac087db5005f40fbd8c2afff72b5de18b969ee7095d62fac2bd226f1c33dd6c479c8774e5089457c52a5c9d055ae51fbb46e1b4fbbc7942cde00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002388ffa483287786562f7ff412848a94a360431ac86a888f14046023b78d40cfb88be59654a2b108548a394bebada9d5ae4ce39db7b8cd9b001244ea7d75e001251fbb4bc1b4fbbc7ca31fc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000237a01701e29489d1bb2f99d2b2f100ac8f8ab3db1c31bf0a05f498ac1560bd259ca2b84cd7721af53a65c8c867df3a920ba25204f0d32128c119ec7a3cec8ad951fbb5101b4fbbc7f1d5ac8a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002afd0348ad6fe2ab0fe797306109bc1306d08c920e658f1311e1f41693fa44d20eb048f47d8004b8c41bf631ebec165e7b20431ad51c7e27ff2d2c5ba5c939fff51fbb5811b4fbbc78a610c01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027fe7d77e2a2008886f7de21761adb17ae79ec96a945443da227a300f57ccce5ed5949cec00802caea0ecc7dd1c27862f6a79048d75a14a0039ae6606ce2b01ee51fbb5f91b4fbbc7bd520d01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011babd1b6d1d5ade6465775168af486ba7bf75c0dd955c230a3e619564342e2f7b897315ca9fac5d01db5a31ffe0bac36d499ed26d3c056c44b05ecc0278cdbf951fbb6661b4fbbc7dd595b75000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020cee1a96d14e3d39d05beb0aa7b460133a768bd7520c421b0ac3ddcf4f06b9976b608d0dcfba242062219362500c54f337f099c56ae28c06343851a94f2377f851fbb74c1b4fbbc782520300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f74c2cc3ba49e2706c5132f2e12877b22b86dec52525962e59644a65adfaac35c2509258330f77132d9f15aa31d4bc52f905c1436ffd554fb09a0bb0bf9bdbe351fbb73d1b4fbbc7d2c23900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002be7ea4380e2ac34a03e9c1f089121c10783f8569f40f18db0ab8e4b2dcfd0cab48f7633503987fffc481c3aff90e72379c1d3e88c8a991a03d8f341072c5a6bc51fbb7f81b4fbbc7d4a1f400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021b9d220be499277e6d4a319f22f726e1d63ad65452e5b3dede8b6566a1a9178b2bb6e4c3c398dcaebf4fd72101073542d7ef4d69ad4e96a0656b2b7221fca85251fbb8a01b4fbbc7815fb0aa000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e51df6864aca2ee37dda0399bb62350f9322258f220c7dd95794cbd6f293643ce63e5e0bca79336b59d8072880c242a86c43c15c14286f46888287e4bc2274ed51fbb9541b4fbbc7a38c2300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fb23c23a19f6c25f4355b577d9adaab7554be82b96c5a83136c9fa1e4ce267433488dd0900b979b54eabd6cd37e969fdfc50a8eca8c6e16a9a82fa2405d1dfaa51fbb95e1b4fbbc7654c6400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026a662a9c6a9b6f62a3fcd82cfac6190c558bba46ae3612c702df1871929c686e94628e9db2c71b1b1f4a02192bfdb985e1bd596288d8061ac753eca6d65f02bd51fbb96d1b4fbbc7d49d8f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002df36b018a1013319d352635d63fba0985f240d8487d9ab6c80ba0ad10be411551fdb0efd7be435fd509edb516d551d3c9622a11d59346ac8914d6843af88785c51fbb9cc1b4fbbc7f9c50600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b4fa8e1709dafaedee48c527f468bd5b22dfca33452d800b6331537cdc68d8f28c4731c6f1f8e361f8d206894e0ad818985bf7e9fee9d75c82a5ef29c596761251fbbad01b4fbbc77777a901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000128259fa424edab7a5a7d49aafc54ea5c6336c283f4cfe9e35386ada69726d66283a3e83203651baf5faa520b40f464653be96f59d8288fbe022008ca5852949c51fbbb181b4fbbc79cc0c500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023107d11bcb157cb081131dc7fb8b39cd5037e798625c38cdf74bd65b8b91604e81fc03477dd793bb168eee4450aaf722ff32e8ec75aa06c8968d0993ab675b6751fbbbb11b4fbbc73be54600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000268e3a5e291026e8eb07f0439e660c3dc4c000c6b2db59ff6b93af3fe084193f398fc471e23792ba86a62b52d5cf81ffc9d8189cbcd662a3b10d9f3a8aee7517b51fbbc771b4fbbc7521c7d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022d36edcbca26b54cc215364c68ba076e81c119bf315ae355c24c6f5097e01d2346153e18b422b2a8abc783f3624af00f333d0e584a027099cd82e2f7185a784051fbbc971b4fbbc7b8afad00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e92bd0a1a954ba1c3d1075eac5eb391b8799e48fbaa7987e7be4696c2cd28cf786e1b14f880e5ed26f78b895b18124faf00106b6cc63c63343fa94be30b8923f51fbbce51b4fbbc771cd9c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012c9926ce60e72906cec5ab517db155981fa2f967bc3defceae55950cf208d638b649b35c08db054d04560c50a42642c835fdd66c6a5360a1d3009d648292684751fbbfcf1b4fbbc7b83e0100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cc1caaa5ed5eb19606b92d8ad1c9c8d8ad1a8cf011a36d8b8df7e7d9146309f1ff3484e9ada178dad2a95b7a937fd2e409ddbe02f096d952fc5ebf077b9fe42f51fbc1291b4fbbc73d320f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a2611ab55f42975e7b9a6aeb361f77978848d7b09764ed26af233b9c3e51c929cd874ece617a382b9b8c4d5050eb6abc511488918a3409d7fa1f4439b3df6d5351fbc1491b4fbbc7c27f0c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025255308ceabca68bbacb4134a5de727570ce8c5b064405047c6cae05f44999d7d0d057263fe378b2a853d9a26b3ff5bd1d50f3c46e18d3d10e253b3517f947a351fbc1ce1b4fbbc7d6e6cd00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000018711b5963f7372cc80bbc468a085b3740ea8b1cce58efaeee0049df32ebfd775d891e3253c6e5ce340c10512262f1081701b5b6c8273b0d6acffc668703675d651fbc3f61b4fbbc78d3b5b55000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000103e198828495da471c4a878192bd85cb56a2d7cb8e3db5d1864f714c0f33ca2837e84abc2a8a65b15bdba03f396755352c4cd50d4ef8b7bd87442c67e887e23151fbc46f1b4fbbc7b5348800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001850ce1a269a166b73e3f287d49ddbb20503c05c7f6fe26445e506e56ffd65ef959dc0d7989468b9333f1db94da9dcf5160ef6e82ec13ee2c8faa5c48343cdbd251fbc72c1b4fbbc702970900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002708753d0cdbe8edc095b7ba4027570925fb4af7b0e241eb6b936f3c80db1032c931e3edf3b0f0a284d0c750bb6d0e90cec9865459dc342333b7d1c576e99db0651fbc9bd1b4fbbc7a4c03c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000207752d8923d6d28de6f2edf72fff8653d3a77f95943e80ed1125c712bc7052c29ad6a9c5644bed9fb95f5f162301d69ea6cb3094151ec1a53ee5b6de3c1e78d251fbc9d31b4fbbc704180000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002547bbb53fdd30ac456d2508e3778eb2b44c0c9849728d37d879a670ceaae921b0cf70d063fc385edf6ac948930ce7adb7c65cdf5e4c532e9f765103abc4dac9451fbc9de1b4fbbc746851100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bc0ccacf557e0c2e7b185bba52bb7cad570e0b6009983d9ed7ae736155bae32230c317d7c9b342244f82cef0cbf5422857b3628ae4e3f4afac683aafbd0f157a51fbcab71b4fbbc7c63a3100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002030b478aaab45c1291f4b38fa3d8475615521e11d95322d57eedcd0d955c61ec3ba3397fb75733c510fe21dcf41de318698c81a1b34b062ab81312a9a9561d6251fbcc261b4fbbc7dca2f401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021b1208defc49de80a067866fb766eb0524b3d0a996894fffc830ec1f737e96d809945d46d2e736935245e9dcfcda5f142faf191834b62e024448f9adb4f9211c51fbcd051b4fbbc708a31200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000230d0a797adaf641305c023b075b10399ee1d91ea933d8c12bab4a3a17cf3894778b7bc68d325b87e00130cbefbd982f19c8e33a18b6377a07394479ba6b97cd551fbcd3d1b4fbbc76e235500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022fad1fc78ac162309ad324c9cea67964046a5bae6598ccf565f04c2a70ae95b6ba9aa2ba57984575770fef0833c99bfa5cf00d7b56a669add1d826d972348be251fbce971b4fbbc7cefc3f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023d653171e1caedef6b8b9e4b1b871b405aeb5e3d50581033cacd6907169e6fedb1c6c8ae4d572ede5969794b244add4f242196fb1a97dff515c447b625b46ad451fbcecd1b4fbbc7ae39d400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015f6b8cf0bdb32a54d18a77b037fa2baa431ec3de09b216435f1b2ac8ceee1c730b92745c6b665ebcc520e591465a150a35887edb20202df3ff5f6e1f95d616e851fbd0fc1b4fbbc758166a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000218f494e1e3d01bf981935050fd373f819dc8464837a5f32eb3aec787a0056b9fe401d431b881734482d47d6f9bd6a5a2d77bfc52d1132e3f755a2d379fd2307e51fbd2ea1b4fbbc7eba64800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001dd36df5bd2cd884d0d09a48f205f4d8b903f56210ebd4f0d0357e0b727f078600bf0ba0c9fd959bb39756aca897a8e7751eeb7a7cb77adc7ffa57026daff8f4f51fbd4991b4fbbc779938800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002aa1d5ee49823e6f7b47cff025cc3c21aa6f09562972269a3c54397fb3d598eb74ce0c6497bacf4e316f1dfe7058e1274146bcd527f0fa5fc8c46f2f55bbc82e751fbd4f41b4fbbc7faa70000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027a197822daa9934937c37f0a091ecd8f1c6906ffc98acfc77209811d62822ab751ad1acbd9a803fbc16138fb8c8b5ccf50b71812dcf41e4d44a792903c259b0651fbd5561b4fbbc766027000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002280d99601f57755fee8233dff921d47ec04ec01ef61e1119c752c604a3e2fe2cefab963c4582c8c5f343ad8a12ce9e8038179ccdce5bfd146a1438d1ceb0d3e351fbd62f1b4fbbc77846e300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016c576ceba82e8947ce9732b025e25d62f95c52f13cedb2d24599b4038f507d6600f5dd08c92a21b589af7824a8495c96522c9b84eddceb7b32bc926d663bcfd251fbd6361b4fbbc76178aa00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000110269bc6ae6bd414bf62d2ae3748c3b09b06412ad7adac4fb1abbfdce43e6983e25070045428c3aa4a446abba9b29c8263d221bfc9939e59dd5010a3062611dd51fbd66b1b4fbbc79a0ccb00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000174b8c0696e18b783bd837057595417b34ab1ff0b88b0d1360f44dda780a3cefa0325a0c1fdfde52e42f0c9e82cdb62f0785e756e9654bbc3e509f2f21deb09c551fbd6851b4fbbc7b48f0200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025cfa2b6c59f64ccee9293f1d8b4ee37322fea29940a93fd1ceb10037d56bbb3808ed20848d9b9dbf8829c7a1a7e5c912a2c9a9074123cf19a9c4c40bfadced7651fbd72c1b4fbbc7e1370100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f556c64beea8ace730d42c23dc96c8d5484d96ed74052f575e5c27fc7bc6f56f6eb281c812768e1ba7fc423ad870f5b121ce61932d281b563585268bcff312c551fbd7521b4fbbc70e787700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e665c75e8963568022794a370bef3e0e3b61a096e27984573cef0521cd16df63884a01743bbde1a99bf104003137ec1cb2aac804f34b14458db066809355bbda51fbd7831b4fbbc7ca54ea00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000282f134280fc1827255e29d9ac342e5874471b7cc0edbdf977f983b80b0ef5c7d8c2cb6c0189154003943ef64c79d725ae4c175fb43f2501369ff117282a2315551fbd8301b4fbbc7f5ef6d01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e918e3de1cf65a2da33892999f03d90ffb9d350e2268e7f5a659d1f7ee04f5efb9e7e8cc9b72850a9e6b8e97abc44076b2279ca9d3d45e2d9eac383b6ae6d82d51fbd9041b4fbbc7cd977d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002453ffde278eb27817683699248e76dca48286ded5ae690a1824a1aa02e96d7dc477b1ec232a0cc265b5ad7d236ece4c26b7457fd873441a53c8043ace8b24bfa51fbd9811b4fbbc7053fb700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029870a7344c9be9b4962c61349deb9b9cd0b6794d25c9b21138c6b21d07fa12e266c36333fecd0df2c386ebdec404f1596af4d1378b56c7767f054eb2b8d4d86851fbda3b1b4fbbc70002fb31000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eaafa3f7ef4ce05083eefdf0d01d07af811eb7fdbd9566c006612185e01c6ac7fd6cd0f54fcca548c8071b5ddc4d27aa645b181f179b2559ee2ca60fda67608e51fbdb4c1b4fbbc751594900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f7c4fc2af4375c00cf82bbb21a98829708a0c13d5f1e94959fd9dab24133a7ec95b4ed0ea414c9dd1ab1b57172ba91d8deef0c6eb68bfc8068cb217302e0822c51fbdba21b4fbbc70f74d400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017469107f16f9a01c1bfdea3297c817f2f69283d94ef570d5982c6c715b8220ece92743599757127c3bb0dcda9348895195cecb2b22565edde825f90141469ffc51fbdbd51b4fbbc7c2862a01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ce6c0fa9f086c757a8b8c36b03586f79815bcdcc60f2ae0d33252aaa2d423bbc8457623d9b0e4ea1b677f735b1c2aae8b6c9d431f3f040e7a0435fc14120341451fbdc961b4fbbc7a09c2800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029acb0dbd409c3e7cd0cbb8ca0a2f7eaacda285f4da2f5ad2cb5c444db5b68048a4325f9e5f7ad4c67d678f2932167f2ef9b3e82a4fae79d3c85da0c338e103ca51fbdd901b4fbbc730253a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001125b647632bc9c40554385c1994bb2a44f84b2b6618c21749c4306bff0079e4c5b40a0c77f7fa7e536ddc6d89d8e2f772d2028fc0c7d1965f1dadfbcb39cf2fb51fbde291b4fbbc718d08b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000200d59cf7f487949f88c842ca06059ea15d8f3fbe19d5620a74b6b3f0a335750ebee694b53467d6c9e2effb5080dcee6dbabff7dab3e4a1ce9df54c0c7aeff01f51fbdedc1b4fbbc7dff81c02000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eeb103a2d7e1bbc3587c083be7d9563af49bd896bd9acc88b8eedc1a84a16945396d172d74842e190b0359a1b59a332637a79d4c8c56b25888745b00b02dd28051fbe03e1b4fbbc719100d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014d6ad28a31195e44f0199415e077bcab4886eb427d7c034131e88c410d16cab783d4424f2b09734bfaf031cb932162ba020715964b674f7c1016a3dae4ec3d5651fbe1071b4fbbc799314800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f98b3a93f55981910745b8a998f4fd9fa5b6359ebb177e0ce6157dbfe9e14cf7b8c2b9155a57b668597ba1047d98196da21a81d85d7b9fa644c8bac1940e084951fbe3781b4fbbc706742b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f8463b52ef030db7b194c3a814583e78f3e90bb798f39a4adcf5ada6f392d5c5c7cf6ad253941372630c189003b7700b3dc068d0984b86406f7e1cf4525783c751fbe4781b4fbbc750ab0080000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000266addc405eb0908ee748e2b80d5ed8508cbaff6f9415d1bfab55ca47c183eeba175f1c802b3652b522936715bb26e3ca3fc9dee9264f7c375ae0faa53d3e9c7751fbe4da1b4fbbc785336e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000234f239b78513b39b8bc9c8f09db3322b7bc4e73297c9b445f98d62da9706321d4cabae013f334b7403c7e4da0da385cd7f599d41a845bf3390340fc58cea51e851fbe6241b4fbbc720889201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022b153e8dde1574b488f55594870f38ff0c4ae654597d514e63f3930ca614a8bf9b9815091b9ca443234fddc84a7aa72210cd751686c0fb2bf552e7f83167376251fbe9661b4fbbc705a56d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011d667ded56b535cf58d9bfd854fa4684437828a6ad9712d4328d65e790b92591b5d270220e0e233a0a26c71c4ee7afba584515c9af7f81d9787fd6dcc8575a4051fbe9851b4fbbc7e9223f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000197f649c30fbf001a55202b442b0980b6e7008288169cd0add6e62484f55be1fe688cbd5251bd1a03a13f09d2323fa2f9409284d1af838592e440b57ba2af082751fbe9de1b4fbbc71ebf2500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028f318c8037b6191cda8e68bb050820987b900b27c82b23a0d9602277c8a96496158de2fae5462f30f270ce9da927c93b83fef2b5ccdf0b1260cdb7b60e15d6ab51fbea001b4fbbc775015000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000216ead1fd19f7c0458215e95db02fc137741bf2de5a07651c67a892af2b0fa96850427b7c3f2c40eb33d44a57c86eb65fa100db856610d3caa700d9ae7ddf6ed851fbea341b4fbbc7b4562900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002df18ba5ed8c4ae3163fa6a52ed054237a7e3ba3e521422c977ba50a64bb953ec62f470552a5db223942f879807af822231f45eaae953806855b938e8336cb49151fbeac91b4fbbc730e40f01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fdab163599d8a258bcdda78f0e01145f782c474bb05b649e7a917a07d567375921c54f416f1248d69b73c571b3b312dd2b4cd670c4048b5ba2db14de429fcd1b51fbeb631b4fbbc781277200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025318b7bd282e1072dc29ab499088fc5a1e5d23a5227ac8f3608be8d03a8410f83dced9f1d42e3f83f01d0c14a0b6af2ddb2fe3c6b349e1f529793494dfd0199d51fbecc61b4fbbc74b68ca00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000273c95ecda982677883b7be1b35b7c1bf1f9b8313507471188014199e1eea24bea053fc957b97ec0dedc58214ba59c85c01da484c5123af7781b1c7ebf21c482351fbedd31b4fbbc7bfdee200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027d87a30e06a4eb641ed333ea199282a995e8a653251cc55bec73d0d75d6664e5c5f6d7e27974f1dc392db26cf96321e52e6a1e9878888cfc5e2ccfb397aef5fa51fbef521b4fbbc7c2eb4500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000160c68e09686cac1f10794755cafa18e476d16704475abf1e28fd9022fd30b71c56fc827cb9833a75f8b370bd1db3c68bd709aa165f31a3d61ec9b4e76eb2350b51fbef8d1b4fbbc7611d3200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000236655dda8482ee52027136a8bd57284b5af5976822973dbb9611aaa92f61803f7604256d0fb46b5ad4316c6f802dfb50aa135fa2f14468c8a7464e8f4556343151fbf0811b4fbbc7905f6633000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a9f37982b7053c1609a170d9cea69156a6f0ffa1a1745c8f4b4cc0d21432935cf0f874574ff33467348d3b5074fe7179a62bf7b9dab551efd68bcbee773a33ef51fbf08b1b4fbbc7470f0500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a8bf769d34ba168eadb7b3427341fd2aacc69e591bac016c48ed1abad56174330d8d919d1b2e7678c21b38d9e530e1f95cf867054cf7ae8be9609c23a419aba851fbf2121b4fbbc765566400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000145223287333a744e0aa40a4717dacc63a0d6342539586fcc7d77267bf9e532cbcce887b91ed1ffcd9a324bfebf70387a329aae556fac2985e1ea74e1bda2c2e151fbf3031b4fbbc78da81200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001730275b72abe8e51c3af1c69d682fc4532151e0a7f03492e5362e41a8255010e385a1632646cdf24518b7b4990be6def31543c6326c61ae7f536ea531fdbbca751fbf53f1b4fbbc79f292500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000203acf8d828f4e56816bbf1d7ea55dd1e62d836761a24dd01b238dd386a4cb4b08220039a3e35f147af32f318838e2aa75aace749b44fe31fa53bb7b98c32e50551fbf4f01b4fbbc7d7b93c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cea54b00218a4a3a68526f35930fdc742bbdd74c5156db94778cc0dfde0cf2ead0671d8308dd079cf528e5df6b890066d767435f0fd1c49ed76c225bb1609e4851fbf58c1b4fbbc79d4c1800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000018ea2378d16423ce13cb171d3d4894c036bd0645e07bb05f24ba7d80fc1475d7839fb821825e80b155dcf5e5ff31c4b2d1dd53679fcca3c05cd7e37f02aa52b2751fbf5951b4fbbc79a2c2d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a29f98ca04379d969abe94cf3a3ee58393bfb82ca332722a59d0bf2689d402e74ddbdd56eb3d5a7aac9a60bf28fcc24750940d19a685670e400cf718f5fb898151fbf5d71b4fbbc74ec61400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d87f6014428bf0ca70f55d3ad82e809ce5c3765b661acc2b66bbd8de84ad489cdd0adab7e3045d3cea7e76047bf5174856fe31dbe853a20b939afd11d443f0bf51fbf8021b4fbbc70f6cae00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ec2e55f537fd2d9828d33c43126364d8f2adb607aa35e249c23e450cfeed96202dae26f102a99f7ba5001afac3c6e8ce1071a359c197ea32312799be86d4c16551fbf8a81b4fbbc7f4557b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c61304728385a88032b23b1447b7cac349cadf191b81fe1e0a5efc5f4aeb4c1b4bceca64a41c0c9cb91ecd7a76d103e23b1bd240f7da0bdf48d5169c2365ce3b51fbf8e11b4fbbc7c5f94400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e38408261093d020c6f1a7edfa58bdb3d256a493e20a821f60fd6156c5e3f1cb794e1e609f72a787fa081c4af7dd4ef3d0661ba3603f477d8a637d7bf3fdfdb651fbf9151b4fbbc7a5552301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f8999734fa5067dee95ddbb70bc84f4f7379bbbec8a66c7df24eb5ab1cf53c1bcadd1452c897681c67d5aae8cb7916a0d3cf75e9359c709d1822d13dc4bdbe1a51fbf94b1b4fbbc72dc65b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001b1fdc51731e112dae64b6b7343c7a63a1f826122a7493adc4eeb9ca28d29e3ef82eb96589efd1774050477ba994d175c5ed9dfbd6fecaa695db252f3cd6cc0d451fbf9e51b4fbbc753f32a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021c0e2bf7bf48d608e7318bb159a16f184c4eabc2559cd17eb9395be499a5a8b8455916d2baa9c1d4c08899f2876187785b9a24445335063eef6ba0b94cefad6651fbfa231b4fbbc789014900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001da98a239f63a88e9ea9ec30837c08415ba511f840d02e074aacf934ef75e4083e0f1bbb25f51124dc49b85dbfa342cf574d77ac29b4b3d5f26139dfcee61443c51fbfa301b4fbbc73a880500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e96a8f8ea81046d328e5aa001dfe615d0c1a331e7631017e3f53e13821ff4cbac21350e03784677be13b7183442ec5b82a7a6f7c9389a7d883ab173df42f865c51fbfbb61b4fbbc716936900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027b39b568332d3fad2abe0325263ac5b343edb3d91926766d1785886bbef8d2ab0fdc9b33ef57428617fcc16a450c4233e867c941d6d1ac555eba9419b085881751fbfc3c1b4fbbc7e4682901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010ddd5b30a738514bd95575f91fa5d547fc840fdb919dc326372ed6f91df06d8115d43110d3c55245d640ee6b30154143ecad55d35d592e618014b7d78176043151fbfc5d1b4fbbc794c99f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000256222b661a2b3442227135b8baca8af3136f42ad67b2f8fc6f21a18d4622bf0e31a85c138fff4fc00c6109891dcd7cb0cc8dfac1e2dbc39e6e9bd65357fe48d451fbfcb91b4fbbc7ce414f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021abc32aad81424e304ca3520862ed1faed2361e4e331f1b93a732340c354094a84472bc541e35403a4ec7484ce2d818a5c29fea987740a03cb23d1983d6b637251fbfce71b4fbbc707e40100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f1d46d3916ba5176d1c670f29cd8a0eeda3324e0f11d1544955ee0d22d32daeeaf0051abfbe58306b684a069b9a26a66bd0f0980998067c5fdd8fcee1fbc466351fbfcf11b4fbbc7cec66200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023fb6d7444f7c3d59caa774e7727034c66dfbe19d9613ae8ffd6beda236c65b158c9968274ab696978809b9acc0f0f1038e4cee681c21f3701eb10c3b3230370251fbfd331b4fbbc7e1bc4800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000133b7a18d9a640465e9b4d796e5b8f3d5f97c311e6972e1820fc601fcb9b875c0916961efdbdd82cf54a14941542c25f2244affdbf10dd14031d331003ac3268c51fbfd301b4fbbc773681000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a184d768a3c3065d194542c53c407638d6a0951d0c9c864a2467252015b97757092cffab52de63d08b19088f82f4d5f3c0f5e8b3e56523bb458878568a9b3b3451fbfdf51b4fbbc7daaed900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d490921d0281e36ea2fd5fe055a9e40e426764f0bc1ac92aae56d9f9a4a34f28e2a65d6fcc3511de7a656edc0345619986f5738f13a4afd3179df25508817bef51fbfec81b4fbbc7d3867100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027898e472c1fcdeaa160febc2973c2a7a619b66af2e75047102bac432a8771bc399cdab68601e3f61dfa5bcb47f597216a45c64cc8bc636e5dcf5f5c3acfad2e751fbffe01b4fbbc7be083e33000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024a747ecd3d711a0a96f4b6cac20ee5d51e0a93e961bb615de4a1b7edfc64c85b5536037daf0702fd9a774a8cfb5dec855902eefb7da6e489e9d5cf37e466c76751fbffd01b4fbbc76ec45e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d39dd9bafed9d25a20430163987dd2839bd5f182f7f9e4613c8f46954eef841323cce6e8009e2fb27aed8f5504c4c9eb568e6ed7e4349204d7927e97af5db1a451fc006c1b4fbbc79c3c6c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002feb2aeea2b89dd128968a0463087be7590704e7700db20e3f06e7e18e31be87678f48d9ce0cfbe4d5c742f1245c1b700e13a1987e185b79a272877f21811e96a51fc00791b4fbbc778011700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002968e1207292f4377d18363623607f072cdd16af6c54e2fe56fad04021b2e6b1fd29fece2090a8504430086968aabdb1195e3bfef83312c5c30a568aa616ddad651fc00db1b4fbbc7eb391e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000227dcd6cc8a6676b49fad0fd85978afb75d44a3438d220164a3f89fd08c60f218196fefd1d795584cfe7e7ec1a6d14cc574921d7936a43274b46ba7e9218136b551fc01901b4fbbc76d3e2b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000234c3e84dc92fce371d6a795fc90b2993e58ae8fad0f2aaf25f44e78b597ea385cd58b28107d8ea286bf6e455159f28a55605e91527bd6a12474177338945115c51fc020e1b4fbbc7194e9c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002be9535debc49d16cfcdef2afc76cf5fa1d31d8bc9e9ef3e578bee80d57fb2244e5e9fd6fc5185a661cd16fcd16c7e7c46689cdcee38b49f3c85690e08dac3a8251fc03ae1b4fbbc76e608200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000194d394b370c956fc1c7439c03f56f502ffa4026f59d6c43e5322d5ab8f1cff40118c5cd76aa3eea6fa024c98ad85093db947684fe0508d2aa3862185c248eea151fc049a1b4fbbc783ea1501000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021e554d7ad056172e9ec8ef634536373e11ea540bb56f0b683f97d99de751fae38c4a7b15830826a22c16579e8f1d81045ac06a2b10a8c5f2b353ba2811d2bc4451fc06891b4fbbc7b0e7da01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e13067bccf6e90487121965fd1e95620922dcf80f0ee5f1c42691adbe68758077895cd704adbe311f22aa888357b4c43b7dec9a4a88e58feffe0f04b3a0a021351fc06ba1b4fbbc7f7765e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001592d757746878b00ea2b2fde92769bcaad166a9a9a814542ee78b285a95843ad6c81e89f1b41052a3566097b3ce9cec5f2a1a509b9651dbdc7fc7d0648d9097251fc06f71b4fbbc77fb56300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000019519c2364dc837c6793045510e565ee27062035ff61f1dcbe9a792ffb21531886a47740be802540f872e45e783d6af3712d3128604bd09918c6704348b40404151fc079d1b4fbbc71d347000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000249aaae727b6db11c485206dc9e181bb7ae16c76185cf91cd9717c1a0ba22d47bd2cff6941285d543a6c376242f5b687c45e1fab455efb25a62c7cd52e498f1fc51fc09311b4fbbc7ae730201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001600bbc8f0dc105f6f4f09ab4367fc87d52ccd75bce438f95ab70b9e2cbcd4bdf2299b02707c90dd75206ef1c506d73e9a9c0337894bcf8743d019a46d9a9c17c51fc09631b4fbbc75c633a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025edcbe328df621334817706b7f2d1c752553043d85bef650db47002075ed9b84268c787b4e9e879b954cf737655e9462fb89060cb0c959eadd01606a862aecf551fc09731b4fbbc7c9309400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c4b99593a7082210ad42894efbe78e952bd9d000ffdcbdab8b7353da23f15bc79b42c8d8ecc9d7f202edb22bc5b7e73deb7a468283c12af8f13c573b1673bf7d51fc09b01b4fbbc7b6b5ec00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012b4bd237258aa06b4b6d72fdb3d47bb95b05d1f44751e2a594d9aef3a0bfb03736e21e514464c839bafd5be3da684dc46ac49105628a8b4c10e21794c1c19cea51fc0a271b4fbbc7eb8c2a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a85f65c6700f7d410a3cf160e4ba89707e4dbf9e1232474b30e526e7210557af36e9b4cc2ef8582f57fccd1ad6054fcd412f1d8384983800a3f5d8556e8da9ba51fc0a551b4fbbc74b9a5400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017dcb0247c739df76bd9beb5dba410ad3919008fa98c7c762e00029b518e31bb65b488c553b211578f74a8413dc98442fd7763740c236cfe4ccad85b9e0cffad951fc0a8d1b4fbbc76ab4a400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002262ef1d8fd476d82e87dd1cb4d514a18a5343e71c28548d2b1f592bae42d0bd2bd8f2856d9e4a3dff3d1741d5a04a8f427051199fcb815de96a722db9a6f85f551fc0ac91b4fbbc7b9425b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ae37e00d39dae29915137656e01bdc6460b6d31dc8b30bc587ce0336c8fb50753ea57b1ae93814e5073019042c4c640af3dd8919b26854f8ae5f3e9fd984390351fc0b1d1b4fbbc72a8eba00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027e40d5afa962c91503a7417357007b91c7791aa2ea091fa8a5243243dc2c1082e799b938d3dd3c70794f57584de26b452aba46fe67d2b3e10d9aaccaab47339851fc0b1d1b4fbbc758f8d300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002448f736300544214b0becc91fd3fcc36d2587649ea74d2354943fde9ceba5064f71932f23993fc6d805cc3497382785a2280e9b08a0eca3e7ec86dfc0f3d002251fc0bac1b4fbbc7c23baa01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000269c21975f4993ea58c90a251f6f193f4efd693ae25d410c93a6ca369e3311f03ff74c551f7310071210e1d4bc27b862db0aad4e19c9843312e4a00755106b5fb51fc0c961b4fbbc7c919ab00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002434395c0ad61f993cf193b997ce708700f82b42d97311af7cb175da12327baceb52a2d52edae604b67da04f744e0ce7e016e8651c7b6336e27315cc54c8b1c8b51fc0cc61b4fbbc74b8d3e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eee8139324d26b258ac145bf296239e8faf64109ec3cbe1ce7d458fbcb4676509b1ee404328e33945670766f753d4994dfee8ee39d20863c129ee9d570bc255551fc0d121b4fbbc74b930b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010fa832188d772a8e337df9e71c741db45fc149baf70d0dbf70920fc8ab5f2dd94a33552fc6e5cc2d426daf9f1f1356df1ef1e341fec1baf6e6afcdef83779cca51fc0e0a1b4fbbc7749d2300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002861b94ceb7ead428fe2bca749b134674c5aaddbd8f00a637927843fae191529f97122e6b6712d04b9d090ce0ebed39e1016872993bd91216fab79b31b43b2e1351fc0e2f1b4fbbc7bafaf500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001cd286528f251f4dcd4bc2fa5dfd7c351895560af034bed78597bee88204a956a060ea43595af49a8202ba257afe40c36bb002141d64e84394d5ebe88d861fb4151fc0e8d1b4fbbc782194d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022f99593c31de8f39fbf2f9680955a136d7f1b4e205b078a3825536449eab9b7dc454c9b71fe47bc3cc6a23bb3a73b0de31463d91d741907af67ab29ba32b23cb51fc0ed61b4fbbc7622c6000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f80a11883aa822f7fc9051c89827f24fc435bbc84324151f9a014f313be126db01e1b46ea5d4549c718d63f9da71aef1c19b4215e04712e85d2055a43700379451fc0f4e1b4fbbc7f3fc3401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000268ab18f3f0569c020e8d8e157c65c367c7a3d59779ac41b5be2d21444149f6041e516c53cd9ea69dcfcbd2739361c8f2dc5718cc8c4eeeaf5f123fbe077cfb2551fc0f891b4fbbc7e61dd700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023226061e211e8ebd0b1d47c91f15821683b34a5b6f5b5e46447cdcd214fa7fdaa021948eecb5337cf87c44f3b1afa6953da4822f1e8952dfe4e1262349166fcc51fc0fcd1b4fbbc700000787000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e0543752cb48c61bda255fea13c86d75a1668360714af930ba029c2b65276182a582714a19490bc02a00b65486239c11cd48ee2ea959f33ec151e2d514b33cc351fc10511b4fbbc75b142301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000277919086626f6289fbc4155838b9383c7c925b0b7dedb1b08055f40dc74c10db493a29cc0f804f76dc32e5cae8d8b8cbcb2a4409f8017d5287c288870dc4c80251fc10aa1b4fbbc70d480e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000018c13d7cd91a7c34ae7df1a89e286e6ba9492b7ad69a6c159d5f8b28f45329b541f17b35392c04e2e1d191ae1d3bbb2745cc273db644ffdbcd2dc95aa42e3546851fc10b61b4fbbc725433e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020f1436dc20075e835a4e67a5763953151650bef1cbaacbc0fe767920a93b60b48da78e24cdccd7cf0cd0d5dc82291c9d1b96491b0b74a159c6b8936b78fb300451fc10fa1b4fbbc7634d3700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ea65d1da891b8ac39df9be472882dbc1cf82df53f57f9912c0b75ac03a885abe3348e2f7e90d75813899c63097c2ee4ff553e79aa4f2bf884904917fae3fe08851fc11901b4fbbc72f714300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000105ff89f931b3b773e5f504bd0bc27e4718f343d3de5751a55d8d782a42d9000e04dee7c91a93b3b1defa51f94c4f953c95cf4fa4ba5eaa250167b88851492eea51fc11fe1b4fbbc7af4ebb01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000233d14607c6472a682eaa051f66af9eab577b78df30376a29175706a6554d0cf9d5e115d14227d14d84e160957415329e0dc181878ddc4fa28c0899070f8b832251fc12f71b4fbbc7b00a0300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020ce2b5417fb009729f04206a6a592a0a210bd184b8861332f322479bdbfc5c7d0e100ec5af3a92bd2ce401dd91fb8ab97b6fc6d2d5bbe6bf1cefe64ad23a977551fc13001b4fbbc7b5275900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fc5a705209458d7daaa5982dfeb06565db7e66d8b5e00b88fea2084071e4e68475413be38b92fbdc094caf3128db4a761e044a567ce4bcc20bab7cf59ad8ed1d51fc13221b4fbbc7f3672500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001602f158b33e56149dbfd251e1ca54ff3d0926ad4daffbf0bc193b5f96b3b737c5ada8780bfa6444c63099cfb9a0ae6bf3f02851e68f5689a9500b48818e3e64b51fc130e1b4fbbc7c89c6c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bf18f26d17d5c71f231283ee9cec3eb5b55f8a8f853e41d60ab95fda7fe6e8c51af82e69770d0fb12188efb61a54a94f66239972ef17f67711713b34e0f5695451fc13dd1b4fbbc799777f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020db57b9a217a5f88f0d7c1fc455ff334be16f9e08442cd0f36a43aa04d4a03bcb117f7c0dde828a1478232306c8e007415558742ba18b43bfada3f6ade44505351fc15661b4fbbc76e845200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ffa0cc5e8bc6cd0d1afda6e18bb1be7aed5f4011e81565d42bb0bde1a384587d9ec59bda7c0575abdf2778d76a55836c6721f5c4ba7d2d0cbfd7ea1b481309c451fc15771b4fbbc7da943e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000018334e55ba914716c204db908fc3d41823ab48014d406c2bf62ead9bf259fd8aaf008c7df94ad9d67fef779966c6fa587e8716b81939a72f75c2adbb89c450d1e51fc176a1b4fbbc7c54e1e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000260c7e7e8a63d9931afc90b8f304997a0c329af3c9fcf8d4fa47c1cecb1899614b2b5d93e1d269015f23bfaa5ada7ed4a1ff777d3905b2267991d7194fd68456c51fc18491b4fbbc74ead5695000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000247ca8ed3676b569234813a5eac2d2b1c8f82e6a4958feda2122118ee2cee432d036e18b5ebb16013e0acce427d63d113caa0228c4e6d0519c75a96bde7c35fe751fc18ca1b4fbbc71e5c8900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000195439fe0868afa2c5f1217b68353490f67c33b896220dd45a5836f42953f1019a5f100993ed90cbea782e8ffa29e4df7fb79cae7f0a8f098d2da44b3382f793851fc1ac81b4fbbc7c98e3600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012a0fefa28fada40cd8dd4dd902f6e0d07c3f63690c59a8a44a6f0034eee2dab85a0f08cc70ff6220010c033da45a5f546d04e6b8c61c9541f64892c2a9b12db351fc1b151b4fbbc7555fc700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bc3f36621fdb16db50b61becdd8a637d435362a197d88315bb47f8bdea99777da422983e03b7dbe18a5c6726273a723c32e087b3922ee5d8ac2b9031cf6cef5951fc1b4b1b4fbbc73a170201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011ffd9493440d238d5f4a74809c294695cfaaef0cdd649a75a6db5c81745509cd58e3ddbdee927cf12343dedbcc6f8a88b2466219c505102b7b2339b18768a7ce51fc1b431b4fbbc7dd81ba00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eda054f8ca19ecb40811b5dbb9999fab9df2dc579dad036a976e31e751955042dcd22904b7246c09b7831233b727f3d91bacaebbe69ec129419fca994a813ac451fc1b9c1b4fbbc78aba0f01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d4e915ee9eb76d741003e6b136da03f2f3f9ecdbcf8eabfdc75c48b4b81d54a419f0f06731d648ec2d63c3580ae2dfa89685221c92d81aeb9f0eefd91844828451fc1c7d1b4fbbc7dbd75b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cd56229afe4058890a0c60e9ca963830fc181e606a352a49145396d89bfd42553f2b9530e2f6f1002cf736fe3226f898c2d20c44eaf269a7c9df1d54d5d1723e51fc1cfb1b4fbbc717a21500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002495b16debf20ac44b4588d18db902870a660d60968aa01adf48709285ce3622b5f6d933e26630e51d3ee7b75cfec454a5618626a79b77303705b41b1b0d9ff4651fc1d1e1b4fbbc787132100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002051bf315842205b4f3abd67c8be1b48cf77f97dbe03aa347bb9d6f32e618c56a148ac7f1e485d706b4e86f150be0ac441a3754c8dad0622d423092e4e8eb83c651fc1d841b4fbbc7e32e1700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000257d5d84a032b61b15ead28fe7a6c13b7681eacf2210133e78e20f2f6dd7ae6f3d7551df6ceedbf2b3d11ee906effa6ad8d42b778f81db24644a74f06b7a3e72d51fc1d791b4fbbc7e8b65500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e20312c9df104a74cf6b3979552f88bc854951ea62860d372c854b8cc28dd56059bc19139f843169dd1124cddc4f21cf98b2bafebee62684f99b13f61946335451fc1db91b4fbbc77fde6e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024865cad359f0a7ce190793d0964708777d2d38e66b9729869ace8ac990d65802198c7153d56ae45726f506dc5439f4280761c6a317ae4c56be1095524577d90551fc1e951b4fbbc75cee4b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d44d982cbc86121bfd55656ec63001e292339aa4958566e57594c7aa83b68abee9460e6c5e3160dc4986ffd388d5e5f3ef68a217132da30a70728ea2da85ac1551fc1f831b4fbbc72e69e700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ccfef04c7cccaf109adfcd612b9cb2930f70291272b47d74397c94b9230ea8e083fd7642ccb3b57c8301ceea9c881c5fa614ddabcd70c5db46b562ae292dbb0d51fc1fb01b4fbbc715330300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a61bcb13842a8099a85f082b360acc2f161794d8dbe1cd8ad76bf73c43a29d2f0557f19117b1dd5332fd510cbbbf9894dc75be649963e272187763ae223882a351fc1fe21b4fbbc7b734bf00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014a3a0dd594f01247e21926a9bb5bfaf9b72c4389fde9e928a79a9dc9a4fc82cf92f10671ce3980c81d6bd8028733da180c3fbf64ad348f197ec1394ed47b93c151fc201e1b4fbbc7da84c300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000294a9e40d5ba114d66fd30d96c668ab63f99b935721465fb8976a5703a8d02a20c4c81314bef816755ec83a5b043c3d36e864eeaaa8e5937060eecaca7fd32d2251fc20ed1b4fbbc74b74ef00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028ef81b9fda16ccdf4bf1aef5ffbba5e5ff093d065176aa36f876ae51d65b5101e78b2d8cc53dd1abbd2efb62af30b77d3afaf6f9620e53abf26bd13c85ff168e51fc21081b4fbbc794157a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001af98c0de72285a8ef8ee7592754f2a9942898597517951c0acd4cb48881bf90c098a799de20cfabe8ffea206008054c16d8bbb7ff6042e23e8124112a83f310e51fc21691b4fbbc7c3071f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000177b50499a11514d08e33c3296108e5b6bfb39fc3d267222e370484aa65ecf15090edb75430038b5542a1b0dc8a33fc01830bb8e34dfe5f063dcb2e75e1368da351fc22271b4fbbc79be0c000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020b5b76a5f561d4c0fa9ace95f5dd70d0b5c5840570bd171eb18f83b1e1a3b9d3d2427b1fd1efc823026335607b67e65c28eeef81c53ec2b71abc504f6a0eeade51fc23da1b4fbbc709ea5d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e2466225460eff30f05e6490feef390fa496a735968e59c4b1a1704151b51854831fdb536a155af8b96d50415cb79cf2c0061c38e6fc4aadba715ad31727ea0551fc24121b4fbbc7a7ef1500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d9a4d0221df0e9c2c35dd72da7b1b708d4b294dab004ede16bb148d92fb239ab78b03b09b0ed35f3390d78bbdbfde8a938aeed977dff87b7b6972dc2ac8c084151fc25b51b4fbbc7a2045500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ba8d353782262fd2e5789643919edf4e6a9de2decb6fcae3804dc8a62f1eafe5b2d08021747ec79e02535e1bebe0cc31ffc3f684bfecd6a7a778ce188d0e925351fc25c71b4fbbc79b117b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b75e49d21d7dfe752046ed43ff6750e79be9d55edb81e658ca87942a24ee80cdd550661323a17529939fd9a1f4968dd00684b69e7ca650877dc7cda9aa9caee551fc26121b4fbbc78fb60800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000201d619addd371422052b9107bee3ab1590324e69719d0636962cbe4e68843c0a97c73dcb545e2f1c754151835cd8aebe3690f5cab006ed57e9c61da05effa61051fc26f91b4fbbc735845500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000264a92999823f2c18284bb43477a3c1afa31f6a9a3c3167ce5e236e5d2a73dd11807c42d454cee626375c3b66862fefa96465f7eaaec808dcfa18710bc7151b7f51fc28921b4fbbc7ee480100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028b0016404a31db356e66a60dd090ca0dd35a4372b08ee06b769fc61f116dfc7fd82bc37e44184b5a5b80d6db12b5525f155763a324777992fa85882692f47a1451fc28a51b4fbbc761b99200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000255dc9a5e65105bddf433573e9c6994b57468041affc2565d37a138c26c3048b236ac3893fcb51fc0412e87a4a4c20beaf7c59e616366652201085f70d17cc99751fc28c91b4fbbc75ceac800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000250eae71e774e70319eae47f9dd73b5be94b24961dd37fa80709bd7523f972f9ae15217bee88077426bbc99db23a356efdddd73e33a6d1d342b757494b8df6f7d51fc2ad91b4fbbc787cb5a55000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ba376c9ead1a3f77323df9461f0c98cd3d31a68f636c6e231361df6080683ddc281172de278fe3194ac13e67b70438417103cd443148c90144e227d218fa1f0c51fc2b0c1b4fbbc7d82e6900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fed4ce25763f31a17660b87ba8da3b5b3455fee85493392fe72b60d64708033b2e691e33a98981d687c563589f14404f3293631aa0a9712a672cbcb64c60368651fc2b711b4fbbc7257f3f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002532480cf280c2c705aa71eb12a4773993ccb31173070fbd7c80dc69772c8de4ef4391e633b8dad5c52785e089f39ca7607a644331718db7373a2db0a8c4aba8351fc2cc71b4fbbc7f28a1800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000299dc258bf84181cbad45643fc27196aafb4d72f09bbb8cc580940bb7fd2f27e2d011490f64b4280434e0754e88056b37d77ef5a9fbe4627d7c0dffc4635b12f551fc2ce81b4fbbc791dc56f5000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d0b46df7dc4170077e88dd1dbcad4f128b56757b5f325916cacbce2e85f3ba383a81b673919ac08a995aaf061501e59584ec0367a62d07351afcbf6193d192b051fc2d781b4fbbc7e98d4d01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025be58c20b4b0080161cdc8e423ba2aedf6787f2c0918bfb43fb52b43f42394e4e30cd0bed58dfd0c5ccc6466e8fa6fa80219ab624e0a8e9b002f215f42bdfd4b51fc2da81b4fbbc724d24600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c911842d0aab161be03ca31daf540d5df987c75aa90dfcb7244bd1d8ebdf28d678b4532c26cd9eeda538727632d15b0e7573feaa37e737583c91405718494aad51fc2e331b4fbbc7a279b900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001dd32bda431b4430d658762cdefb1620126402113b56c0d30e88755e5f46b61a030bdb7b227490b71397ebe6bd380c5afb95833da40854084d5263d56da70437951fc2e561b4fbbc74f55ef00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026e94ae9b0e614063b5c4297ee58a919dbf4fefd68ab0a00ecfa339b3ebf47d165a9aa85cc48d522c875ddcfdf3881366cc0db90d364ed815788221321d37d30651fc2f6c1b4fbbc70b480a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012e951252779eee245daabe49b547bfb1fa816acf7a5aa9488a402ad9a044d237a59f32f0fc2f4c0da1d1e6c8a68223e05d625b85a60473d0cac30b2f50ae42fc51fc2f9a1b4fbbc74c4c6600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a02fd444e6afa1cc8fe197cc3e2f585dad968066c5088ec65ae0b917ce3d49dc09b5c1b52b9d8cb0aa0afdcc24cde7699bdb5999e4ffe39aa70da53de491551751fc30461b4fbbc7eabab700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000270eee3774e254311c65d08a0dcca21ba9af4c6786e6b99b03fcb7663fdc1c0bd8017098f823db128269a5b2fd213f9e40149bcb3fa0033aa92ff88d089c7426651fc307c1b4fbbc787485100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c259141fa10750f93b3e4c5aa0312e20e556c5701f09e6c3fe31a796b776e4c736becf3c614a4cf41a18b91b3381a72f08c79effde68a886563d728eae85e05151fc30c41b4fbbc79d803f01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000298cb57ca2c95019a0a39e8c22bfd0281d9edbcb1342d47655701228e9ef040ca22f271912fdb43070ce11f4668e271be23b3930e843054239322a03419e1e5ac51fc316b1b4fbbc79d05af00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002982949bf2979785eaf777edf50056683ee31476a0d547106cbb14bde74bbecd396193daaab5db9a21ec55a8d14aff71037fc3eaad67dfbf84f2b57c9e739574451fc32291b4fbbc7fa644c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022350b5fbbe3b47acc03f6d210c621c046e2eb1a25824e8153e60b8595ff0d1deccd90529784ae263f790156bd0049f7ac7055f4df7fa34f77acc4138b9a79d3451fc330a1b4fbbc7b6354600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002109a213a310ab44315cdd2a94085c89a54daa463324c8708cab35f021f4eb98bfb13e0620bf590b96746eb2c970190d9789832eae11005efd0162dbe09a2cf2251fc333d1b4fbbc796c3e601000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029e61ee04523695c15c390597af0eca5671fcb6ac000f49f0d39fd8149fb5d101ec864c3fc3bd53857d2a3f49fa088752fb8f1936907cf60067d80dfe6cc8acd351fc34ac1b4fbbc7a75dbb01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002169587272f2169fb1d1f17af0f2bd5b349cd341373bd4fc58d09c22b49b99d2ba62021de6071df89adcaad2bf3b18b00137e00e6c8384b0e9e28a93bba9ba85a51fc356b1b4fbbc76c1c9100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026f00f953e9ffe909eab2928003d440896a1034544f2534d2d2ccc493f56f1dcb296235af7b7baf12af790348ea64ac7fe807f3dd2fbd6bbbf3f92df4c65cfe9c51fc35831b4fbbc70a61ae00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020770bed95751eb7753783defa6b1af28830b94a9c5168160f78860cabdf008c8e816eacffa84a4fa213e569a9b60ebabcf423be7dad8dfb28ce98faa7107fcc851fc372d1b4fbbc7ddef0101000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000207af9631edf9ccddbf06d5d55ba88b00f4fae8cec59cb94d1caf003485832126c140631b3c45c03cd6beb110194cc3fc41f2742fbb200f59420663f2c2c46cad51fc379c1b4fbbc7898bbb00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d1ca69ab631af249607f8603baf332ec51ee91c0205c5a020d4f65168f3fdad3684767e44963d5a14fe12d88ee8b897516c40288cf722e62fb7e010a8a82e1a251fc38221b4fbbc743089f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c7d20aa6aa9d29868ce1c2ed0b56c4f2fdb372f87708bd0eb6ffe7988203684d44c79af88df88d22eb5d0eee8bfb8e31b0f45b90868f36fc03a6a9f1fbe7443b51fc38f81b4fbbc7fe0b1700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000252c646be709fbad244ea02ae0c083fd590641162aa0ae39f69c8ec6793262f02771bb8fea356d3317d4c1c53433a7600518bfed6e66037720e087cf4572cef1f51fc390c1b4fbbc729c0b500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c693f1174928d24a14da4d7bde09e7552a7620c6d6d47d64354fbfb1d95e63cc54b7546b6a8bd3ef1781cc84171f18e8c32af43f4b6e5dc252c90d1c81a6e18951fc3ab71b4fbbc7d9aa3200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000201dcf922a652e22e749da3b8ee8a253180c663b723cd88316928204ce6bf9a629ac3eedf3073d7d84d9a58e680e84a7fa593732f6e8d8759051e185d755fcff951fc3b0c1b4fbbc73d38ac00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000254482faabaf6078feb2a63d47e92d043dff51d138dc952fed98f857cca8b26255e67d005083c4ec254cfbb07dff06e47b59535d7f0b430829a9cccfada9aff3951fc3cae1b4fbbc72e844401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000112659a710b52c6c095c444779bf9e22f8dd592b57eca025eddfebe8c1328247b91a1e936fe9c03b3d61f58a30b12a192aeecf05f8859f227abbfe421e445fc8351fc3d8f1b4fbbc739020a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000187f8e13ec3b6c13bba515fd83a11e03d28fdb29befbef63d28065c2f89927b9d86adc8b0a68ddf8de87f9e07acc2737734f0ab4a82b4c300f14eea2b0457ff1751fc3e4d1b4fbbc72ca11701000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014e8d8ccc885b5e62a941b773420be5daef4e73ba20254f935e636858137341ecd4d2a5e01e5beafcda0e8fb5eeab7d7aad854616b30dcb4eee2420b26d22b0f751fc40271b4fbbc73c890a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c8fe9e8f3c20719045518bb6a8e7ae68281fa0181d8ca427d0f7a1815dcd3d59a570516b9a8476d1d69746e00e7020584855e543b9547b80a692be14af627fd151fc40231b4fbbc7a26e4300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000239e43291de74cbf285b2ed3ccee9400a54121ebaea960ecd9db3490b439286a764e1de9a33bb14e6868eb8c0877e50360f808cd2f41cda4ed9527e5392961d3051fc40701b4fbbc7a2665c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d4a780e3ec1dfae9dbd040b2dc3050bde9df04973a1f22f05436ec5e2e2627b45394f08eb4d7de8407575fe0261dc996800a3af5941b2c7ced8a8a6b3e7acb3351fc40931b4fbbc7fe3d2201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020a3648914e691739670a9b032a18b0b5de095e337ac4442baf75649c324dffcf7d2d12d604a9771aaeb547388f58f000805db2a8e10514ef3c45986d95fae7d651fc41851b4fbbc723390280000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d9dbf330513da2f86c6c86cbfba28290e367b467f38e04c5c54ba2eafa37c347f6c0b07e4aeccfdc432550f88874b29804751567eb7a09011f464137b3a2587a51fc42b31b4fbbc72ab11600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c15bddd0b1cc9716dd60f28b5ef6544d232372216a102d36837d53270843cb0e5b9d13167c0f409a76f4d7338b1b710a71fd55c27a05249dde3eea28fe0204c751fc42c21b4fbbc7749f4200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f857ef7d1b49cee41a4d374363ed9af31541ced81076909c4a2bff878b2f434b09de6eb8d96b60125058928e892e15ca9df887ed1cbf108bb7f57b7285c6f34451fc461a1b4fbbc7a4319701000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e88a8f16ee62f4af3cd7938346e12cac5bbd76d46983df5461610f22d1947564f291c007fb78c1b349e77455937ee5a77721c40ba2de0fefeb8aaf197c2e4d2e51fc46551b4fbbc7d744bc01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000140330ec651d105cd3128f84ef8d5e38671fec21c4ed4c250be035b4f1662b0ff55352209eec8bb2dbe99182584cebb524bc036cd43d20e527cb4d6da2ef42a0051fc46771b4fbbc72e788e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021f088789fc4dff2b84392b510c8ab0d1bc9cc908377122c2e2825d172955724c9a8226ccce60ed7320177885c24ce428b83c8b54664eaf89ace4c7d1c46ca60051fc46dd1b4fbbc7da1fe300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eaf84937d0e61281b0393b7e53dfd2aa806114202bb52dc78c964a531c1cc412d0b7f195fad1811ba16e146951b43736d9e8985bc21a21ad564f1a1180b9c2cf51fc47311b4fbbc792beba00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002960ac965563ed5c1edcc15696102974e00b14e4aa2bba7e9eef416f616ab7addfde0caa8c0848988a1268c286970132ce92e46ca87e2422160c09e1f53bd7b1f51fc474c1b4fbbc775b8cc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f60948115d581b90ae1003895142e8bea329228df92ed8f2bf5147161ae5997e3f3a7b4481e8ef11ae0d63f237f2ea278960f22f5b59d32a3ce3976a159ec7c951fc47c81b4fbbc7ea8cb400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c90694ee72838c346839aa970919afcbaece43f0cd801f366d10c469397b03b6ac19ba7520220dfe9efab2575c295ec5b2a80ce2e6d1d649170bfd9b3da950e251fc47da1b4fbbc71d194d01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001654a879ca169f26534d4b432884036a674d7001f0022c70d313856c1872e1ce71a2c61be8cfdc95686e6777545eee273f1bff86ce6f6022c123af954b36057fd51fc48131b4fbbc75ff34300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029f9f4b666df03bc9e1a011a03895092c535df7b1e9d5f1f1b8ab2562336ad7d73393969dd494ec5637919137afbed80292b8bc6b7389956913ed842e06f3761951fc48211b4fbbc75fe1be00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f3592d0d112a1ec3ada2ede340279039a629f55f89ff6114a88459f68fdfdc73665980e3c7e38c1695f347fa48af2e3916993a4d2df841909ae2b70487f4e45451fc48c41b4fbbc79c8d2b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f7cd07e89730f0efdc9b2480d6bf8c03c4ab83116e2fc495e5d3c3367f83178cbc044d9aae79df2a460e48c169b1c9766b3e71d27fd1b083d895621ec8db5e3651fc49261b4fbbc7f5808500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021f7d154d609d35c577b22d21068fbe876713c842b593386b3fa914d9bd27a0c3be3bd29cd06e520c125adf47906f746a50200108c0d2d03e0d7e41d13fd0e6f851fc49591b4fbbc722909200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001846ff3de344c2194934cefa31c5fce813820e64345e0ae95e9b8cba37658fb9a69692873bd1ff4f644877830eccc571b8250fb22bec79bb616e346c52d0433d251fc49b41b4fbbc7f2abad01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012de6d57e5f1f6deb927c4d6ecece4b3c0f7ca2a38ef886e330c3ea04d03ea731950e91afadd97154e58bbace500ddf38028f1a535e679189b5c130e82734fa4c51fc4a4a1b4fbbc7737d1300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f3b809e9620388ec36460d4bbb674748282dec81642dddc7442b9a011f36216bf178ad0252b8259028b888ddd3a97011c1105554edeab3c214418a63ab5ac74e51fc4a6d1b4fbbc7d5548e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000271f3cf59e514128a891a0324fb1d3610e4cc32258374a0878d76e6b488932dc80de189aaf8ed11fe44aa22ae9a4b6e19eba8da5f7c0f5d3d90982c58a754372551fc4abc1b4fbbc7eaf56a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000188870f2dabe6e5567d964d971a5e01c4f46b467688609f0369a481053aec9230f3bc3daae6d77185b706f3ff62f7273ed14c0c8dd0d941238fee0d1fed85023851fc4aba1b4fbbc77adb0100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f51b001b5f9a19ff496a0aa16f3577342328034998ce64bb180bc8f13c4e75073a158e4f31d01422ea8b9800c903610dfae4c48fb2c6bd3f6db5f47febac2c1551fc4b311b4fbbc781ed5c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000143f306d1666ee72b74e2f7a6e51f2c3f51cd7cb48f0a7fdc348fd67540e90dcefc8cead89a416a407e56d00a455c41410732a26483e1eaddf6ccaadfa163f33851fc4c581b4fbbc716f7aa2a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c82d87dc18a947cf6cf9556e96f93848fc8ec255d5b707909661e7dcff9cb0536f3472831d969ef862798de804242ded6549383d55c70f573d74b85d63cdc07151fc4ee01b4fbbc70b666700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021e6378703ea4f8cdc19af8622544a5cdf2e05f6a91b423b1fc7921e9bb82d93f80f8394ca65bbad42488c7c947a69ffda4573083b34f6a7c228e49deeca3dc1d51fc4f671b4fbbc71c80a300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000176acb03909f8137330eb7fa9326a02e32beebffab5013c5fd67aa2b5384609ec0ffe04b7cec8c2dce4ddbe98cd4967cd5c8d518d64de03304578f81e741acd5251fc503d1b4fbbc7f2a38100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000200bdcfa7b71f47b999667d6efeda0f24b38f41029adf157660ea944a8aac2cd6f7c28cdbdf4d2166e0e8b3ee6d1cf707858f3b6f43c11a9e47ac18f16b03909a51fc51981b4fbbc762080200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000150943790fbe5bc25d47887d65f39a10ba6c658a9065cac9f3a75535d8f01304670432567d851f00527e4309a3f6003a5c359e6dbc12d332d04a89616e1896c7051fc51ac1b4fbbc730c58800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001bc40238f53d779424091e9cd3fb72233d46b20f4ff0e536cb687496d9b1e0d4e8b5c8a1d1345252493e628cc646adc7b2623e214876cf7c5fb537b452d48b0c351fc52b01b4fbbc7e4b1b100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021294ef6225e686e2f4cc36ee286c7448c22b67901cfc1686e6b1d3eb9153d2ba4bfda4e5e45b1b78b936d3a546e81f0052e1ad004d5557a18a3527563994877951fc52d51b4fbbc722a5ac4a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002308e13939622792a2e780b93d44bd151b542447fdce2a7ac6b3f4b265989d32696d35a22299807ae9b52c67a277af69522e111e1a43fd40d71160a7c594ec3ae51fc53a11b4fbbc7865f8100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001b6f5adf6984e69d6be00cb639d616f80ea7dfdcc2664b840ee8e1614358bef810bb4651db837e3aed380f854c08d084a1e0a19393d240211e664d9ef5b5a172c51fc54a11b4fbbc7a2860060000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002daa3f908ab3a3c49dc32194afaad9e023138ffbc6f6936265c1a08b4d3889979b6e24176221f1198b1d82a04f94d06b4e6d4cf1e98e583e5a7324b07ca10c2a151fc54d71b4fbbc74c924600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c48104a71bd99e8b2e0459be9536bc6bd269ffad3a604f34e8bd7189182eaf14a6a39ba5edef9d2f5f39e5c5e572d9aeee28df1a2a749140c1c17d4f263432fd51fc54e61b4fbbc7d1503300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021cc8d4f82ea796d9cc47ab42975836ee12582e8fa65352c678a8890781971e50d5d0eb5354ee8f48ad916a4c5ca1bf287a3d0d20ba2aaa8a73c924c6458c35d351fc552a1b4fbbc70f2a0500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a2088d2e43a8b6b31bd71d0187dbf37288b166625dfda47239110d0b3354fd22e07dfea507c2bf10a943a4bce98ab57cde5a168489b87ec13b2c4544fcaf032d51fc558a1b4fbbc75550fd00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a5abcea565038b43150d06ea779d0e503df7bffd6f86598b10c2831ecd78f285602bd7e2b442b4920a4203db567f4f7835796ef5277863b40160add1eb8277a751fc55b41b4fbbc7ebb27b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002dcee366f7a56e4fdc0e1a93153726b60219a5a80cb4f87dc58670d39e9999ee87be6c70ffce90b1fbcbda50c5f61bbff43bc648a490c32550565284b09ed648051fc561e1b4fbbc7256b7d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021cb9deabd9b5798da4a20630cce293d006d8b404597a2716f8545406be476dd6bed33d6a98f872126df8eece092800ce7458da4fdad6e5b48f61a55279d4154a51fc56ff1b4fbbc790a858d5000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e3a780bb5991707cc22125369daed058bc51e2bd13490518cabbf5f8b46be8e7c7bafa02953e0f659a37cfc45aad2a53fecffffdf110aa693986d61a97a0543051fc572c1b4fbbc775bbbd01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d5e4353b2e0807eef0eaf9ef85a01051dd25a234cbdbc4ddea4b2ee35c62ab7fc7fea368b90633cca32213254d5387d52fc6e6d762d2869ebf0b8494b4e47a2251fc57931b4fbbc70d182c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000165b2823f87010dbc5827d85bf805677acf57940c8f447d790c8fbf1aa9a2244dd1a257e03a14622a582aebcc20b125bb2999513fbd407657f7613331ad60eec651fc592c1b4fbbc775242801000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023ecf5ff4f3f3c194f3d9eb09335870508220e806e8b431e838d8020cc195762332571889b3b47c54868e374c7f8ee63c7c623d0f8bd3a0f296c7b0e71132536751fc5a011b4fbbc7e0b25100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015a5c2d88c23c48e08d7008ff1fd9f24e014d40f50ac93e978ba4f0672e31e252a2751c63468b6c88d0ecf228d79cefefd384663803ce962d3d12b7e519eb13e351fc5a951b4fbbc7ed535615000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000293628b508cc0f839beec24bc2ac2184b52705a2e329be68719bc4ffe73c10dda1c4760410549996b0ceead7b0ebe4aae78121397c253e81349a113f443d4afa151fc5afc1b4fbbc7460b7100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029c27fdacaef6d3233d39854e89b89e0a63e9f71c8162142763343d8a3356f96e861d33b68d89987ac558d73f488b1709d50597212979759afdbdedd2e395b64951fc5cb01b4fbbc7364a4700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001da009207caf105f7d2f03eb994590daa485970f7cb429530290f7a11ecd3a595f4ca2a979ef40e33682387b7459ea763f6069516480ed6ade59ce9e14b24787a51fc5d271b4fbbc72e154b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e330c30d9501f512c79724efe93c56b430f2ee82fa0393345847c5f4be8f1f16ef63c8ed0e3b7fe68e9c3c4ffe95cde232b137d7bcc8f48ef9ef7924609c0db151fc5d0d1b4fbbc708810501000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ffbb1502ac9ac35e61e3e0e3c33c3e9947f6e7c8c33802ab6d5b570205bf675d70a43dec15ad10c02aa1ba9c1c271918c480d7ba958dbf23e40213e6e9be34a851fc5d8c1b4fbbc7ffcf5900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028d138ba806cf6421ead07eae5a0aec0daef1fa09d404f8dfe1aa25813f277076332a31f26ae72e5819ca25aea74be467462543e8983bf23b7bb19a83d8bb815651fc5df71b4fbbc7575c4900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022cad8bd84ba0d1660e6370980b7e7cf06fb455d7c44623dad5e313852ea74368e0a96422c181164d8c508a71b2e665b85bf047ca11cd4e0426dc897c875eff4151fc5e211b4fbbc7bf311b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001167a725f28cb8ef9554acea819692dacef2ae4d9781b2f3f63a73d3278d27a1bab0c54144c80d0c8a0f20459a1c65ec3852fa730eb92acded5cc20c9b55274b851fc5f141b4fbbc765e10c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001da0310231054670161858b1380a3eba9262d18e84828b250cb0c99c8b92c0d79e95483d0d425c5b30d1d95c759ae30fef8ce67ab6a3b796a50e8084f9b1a65cf51fc5ee41b4fbbc7033c4e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002450d64a3bc4a7d6325c79a34cb597ccc585fd4f72065ae6ddc9011d320d4fafc4334d4237904aa9267f4efb10ba6fed99e6384cfe78b2ff133cb43ac20a52c2051fc5f171b4fbbc729611f01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e56f335783d4a3de5e0b24eabad217318beab80959acbf25f3fc1d00c74fb5dccbf23ec04c2fbc96c93157db625219abc49388efab2fdf8c65206709d76fb0a451fc5f7e1b4fbbc711bbd801000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029cab4d56299b2aa0cfd7e090cf53aca1543752601ac67bb82d02a52a050b992a8c77bd946a0fb1fdc357a1d94c3018b38e32355e6ae91a44d574055b409f917c51fc601a1b4fbbc727694700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002462000d129ff39abfee9e99f305d6001b952dd40430f2b5065562e4a0dcb390fe1dda0512303dbf51f3a48fb0e8941cda79ca2bf783d63fb8c37799ee4c8c63651fc60f41b4fbbc7fec78e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001682329872e07772b169f808a873d12a9948b9a57833d4f577416dd7f95ead3f8080c575d66808feef2169de49d34a101c77a91208b0857d8ccfbad7842dfa5f851fc62021b4fbbc78baaff00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001136835e1f12ac20dbda0decc0a5778250e8b8678b8f01699fd9bb4619f7bb9a60a60c02b2b80b53d801043631f6e94cbc9efe98f9bb72b9fc2cd4ff8f6d5f85d51fc62c51b4fbbc71e0ae200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e225938cdd4b8e993d0c4d617e39b2ce2dba8b7b359e9c3628cf7a32a7e509c805f162320ba64ddd5851aee63920d732b74262267a96d5be0dcc7240831eef9851fc63111b4fbbc7ad846a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020156f2e7dbe0fde7b956c064343f2d9d9b9c41ea4d815255f994f30e1ba6a44557596b748f3eeba462a526a1ac52c36d4c861b9820bb6c72840dad91c4dbf50351fc635d1b4fbbc79fc62b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001292525e357babbabe19047fee5d81d6cd8552d494d78931a88381055af8a784784ab8bbf9ffe477cccfe301a298d208c905c63b263c7720bdb610748c5d1c42f51fc63ea1b4fbbc72c5dce00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029499b484d9e50e8faf052d9295ed9a72306661ff60419b8400ba8f816a001de9f420c79f82b99d1a9c66796b2ed31731ff886eb3236bc55e51fdf3f2fea69d4551fc643e1b4fbbc71c4baa00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000280dfef5e6dda4ca86c2f0cb28d7d25613337ae1b4ee735b3576993ba662c9245765385cda2812ccb9390cff4523e61e1117217335210e708076ee5fb9d2cb8dc51fc64d11b4fbbc776c60f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002949b9eb6e355b3a0ac047bba75e7f08e5361b3dfd316dc6304f9e3afa789c2dac8ac3de461fd3369a4e3574edcda4b871fd2a579eaa0d93a34341f85b3d62a6b51fc65cb1b4fbbc7c715e200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000288b6955e0657c18df86663c9c8f4d3bcf55f47919104a0ee078ebb9c8e7c5385a32cc436fa2260d12316b72832a73988a4f78765d234939e5565a6af7c11f22851fc66591b4fbbc71876a400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025ad72632266a32632fc6084337edccee95f243e0a85f0ab3e5a806c93eb76b25025cc7217850b15f21ef264439c52f6f1e7061330769762c93599678c9e825e551fc68cd1b4fbbc72a990000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002541f0e2210579f9d6a42a588f4e6159fa43bc57537b237cb53cb3028861336940b2117d35de281764959810631054fea13448d5e091ae51b3787c2b7aea5750f51fc687e1b4fbbc77e513f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016325fa008bd46c0504507341be99d49d00436934a658eecb8d0ea20044a6310fdbabb71045998460f59823719588b57f30df0ae12f56855756aa10c739cdeb7c51fc6b5a1b4fbbc7817ad500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000191771598cec5557f3fd4db6825574a90da50fd62c6af75a9aca41b158781878acccb9d8855d37388c2f6433b763e9bad428b7832a2d903cbf5a0586564b7d38b51fc6bb71b4fbbc70ae9be00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000292e8472a2e319ae6e6e82ef0562dde0087f0c6266ebd50f184ea931cc7b96dca4c6859080b5b56d54a6bc86a7e1d056712c3ac9cf14076a4ec340fd8a33adc3651fc6c7c1b4fbbc70867f000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001b99f1762adfde2877b607df75a8f625913a0a7fef8adb27b4fc3f40a83881d8e30e2b714c75db198fa6e0b6d2decd995e72fad7ba999232f08b8866059b6ed8a51fc6d381b4fbbc7bb4c0c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024c94d9dfce87586d71bc4dd148954a2a6cb56544582dc4fd02da920b40fa21829d9ca111d6676816d8686f771d6a4fc6fdde7d33760d64ac3ba9c565f9dfbdaa51fc6d571b4fbbc7878a0120000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010412fe89f937649c7ed982942608bc90edce19ac2e49e9206e88933766c7535d13725aa62d586f0557d539e7707b39dceec0a7c5a8017cd1141b62c25bc2f20351fc6dd61b4fbbc7a2d06200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ac343fa9c446b8e7f93dfffa28ec94a961fb4a5127d7750c3f3a59600eef1edb4e943c85c851a2d253b81e8aa708acc4bce97208823b6267c2dea048b3c28afe51fc6dd21b4fbbc70e7c0b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027e4e246cf66939ae7dc22808fca0edb7d4a3622a27db9b28ae9cf499b063c1df9f9c2af1457121409a2d81409d1fccd04e1288ee8d58cab59cff0816c2389eb051fc6e3e1b4fbbc79f349a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ea0806765115ac1204a08d068eb95278cf51ba973173221c2ce538602afb14647addfb5dd9b9e5ac379316b3179807f3be0aafe42ccf665bca9778624c76217151fc6ed61b4fbbc732eb7e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027b6b0395de90ba2e5352a0061d2b2c148755518fae74aecea1c830be5ce7347a60cbaf2c14f68df842e9b5b01203d168de30bddd2d7a82e74f9e313f42f44f4f51fc6eef1b4fbbc79dbeab8a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f744f38d933f9769c39da78901489802cd67e2fee8a312db0f2636df418a8db646546a8c5957c406d1342e4c8a76a7767745c2e4b44e68389660a50c48c6470a51fc6f0a1b4fbbc7a7ad5900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002517f94ab656aece2380f368ffc45ded19a55f8f7b34fd7c05db2ff67d54ea86b7b41a4088ad475ac6437c45f2659813bb8b7d93cb6a8b84e390cd8454e1efe3e51fc71b21b4fbbc76a0b4f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002aa355c5bd8f8987911f2b770f8be088e3249c1eeaadf9f037d1caf3862f9a3ea8d5a9a703c74fd9b9e3d4f4fbcafbd2a1dbcaa14bc151ad3d30d33ccf09300ca51fc71e11b4fbbc701720080000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a4d81a41151f8037ebcd9ecad78781694be36297a18bad95b6fb584320fe2fc5d3caac4f10cb19f63adf4ef03cdd3c28d7df17e92baee8b0d95458ad73976f4d51fc72091b4fbbc794843e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002df2106b86d1e70531e4dfd6c35edc103340fb7669d3b76e4ed7059fd537695117b31530a27db11ffea15926468675fa6f53adad99342b13d22b637399b7009cf51fc72c71b4fbbc7084a3e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028de2512884efe1559b1e2dbd7847dff8a7a16b8dc106842613c3d7139e98f80e30c6af35eee5defe56a385e792997e8ab250f4f85f60f0b71eddd759975f16f451fc72d51b4fbbc773d11901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002126b48d3665fae4586cc99664a13ddac8ea27c2d4f7529e36814106804b277c66b5c1d07b64d7f335c1ffadb5cae0a475bed245433eca8c448d145881337c49c51fc73421b4fbbc776cf9300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cb49896b583b2c3d7ba68924e10c99dad43d1be9425cf6dd053cb227ec184d664a82c7c8302bad10d92d3b2519a98ff4b81a8447c492f3c61362d0499ebcd4f651fc739c1b4fbbc7d6814000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000220c182525e0a5fa8864017573440551851b9cbaac071ea28808e5e9524a20479012757483473e94027e129e6d8ae71c9023bca937e6903e9590134a70f7b1fd851fc75101b4fbbc788604633000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017ee80b22abeaa19fc67308b9c06cfd582033620a75fe1beda7480775250b41866614918699c17384924a23bd2ed76978eb99130277b4b82c3ee5d405ae2466cc51fc764d1b4fbbc759040c01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001055e955336b81fb0bdfad6448d55e5b2c6ff439a4db4c150a7e244e2337d945c3800b50e8fb65bef7446fec9c19e7db96314c7af16fc94591aaab39f52d2a64651fc766e1b4fbbc7360f7d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eb1b4765402ddfa5db5793eac91f7d754987c3eb9a569d9a9b7a9be3c7d1577cb587989d2931cdc88155a30714766e61be055c4eb6a6b264f215f7ae6212d43151fc77291b4fbbc7779d2301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000287f9789a020bb5348d06ab7a74ff55918c1887e2e832f8b1a63994ad1104ff5d7221d782439273a18eb04ec4ec80f2b78391a5489950b8955d0db57bda61970651fc77161b4fbbc707190c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e91ae3b57de329feb30bac19c9e86489ffdd2afde033c559acbd2b2cee6b274500f7a3f4601e2ca556bd55c2dd840b85af2b8a692b2ff9d807be38a1d72ed33e51fc77691b4fbbc727372400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000293ffb5e4cb15df476b032ab08e28b33027e0cb66c19a055895bc3936368bcae078be73bd0bc951598b1df969b27cbe961ccefdaa42cb5d471996e3a409df627d51fc77941b4fbbc784360500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002590f5a021de2b3a095893259ab0abd87e51ef329a419df490b8bb8a3c853a862533fd7820b00e67ae0d91747daa881b83ff8eb7cd100e72be28f771f84b02f5151fc77b51b4fbbc732825a33000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011a287da06b68feb541cd719566fb34f02f1dfdb1f0da0ff9cab20ccdfbc5cb79f4767e50c53eabf4039d63e86c6a72b27714c4089798253bd4a3c8611b1dd0eb51fc788d1b4fbbc79d094100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001185ce2ec22e08b64ac8ce40989972d3afd706c1963099828c4424a37610c58b3946dd7264ca344a5dfddc5a99e17fa5bd09f408d87c46e063fc2766c7a3cee5e51fc78981b4fbbc736970401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000160c855b6fbfa2819719d19e70f35dfbdc6425ae54fa11abc0cc017ce181a6d5d800c1aae07b73ba39cbaf6eb6663e394ae50acbfe7bb9ac5130a6518e0d9639c51fc78bb1b4fbbc73f164d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027db0a3c4014e28f10ebcc18b38d20705403872ea06f7d70b663aba98cddb6e33ee36b6c8234a4f010962118674891a53ed15673d4263bcb9473c15c701395e3151fc79a11b4fbbc702791f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020baf9de6709d8b1868a572d76a98c5c49d67d2bb0c6a879e6f300d0d9ea4262d471ced4507683a93341642786a1ac1d61f8a4d1b2a17e69f78b2d1e71b0f597551fc79c31b4fbbc75d74d400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c04b699fe2f3263460e9869eabeeaecec7d1ded10dc467ac27d0516caaa9cf44bd79484fcce26d2d8b6858d9848d6f80722b232f097a73ce4569cc33f212462851fc7a651b4fbbc7bddd5915000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016907ed03a06ba2007b0ff06f9645d47054d9ca3efbc6f4af78aae83086e405cabd336eb3a5d6e670138fb66ff327c40cc88c55c61faaa9de08384a4fab5ea39951fc7a9e1b4fbbc7e1fd3b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a372861a8ed097d2cf7d74c0feaecb6b207f93ffca22a5e6f95837a00a93b7b9a42df89ad1d4007a69ddae2d55605629a2fb3f8b5b70f01952698728fe8341a651fc7add1b4fbbc76b118300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b18d3a5d0c93f75019427eddcc0d10e1f7381c7b864b0bf000661c1ca913a9f4012bed383980c9b522685b870edd10cea7304a0127ceef6fe12c517dc422cb6751fc7b451b4fbbc7031a2b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d6ce25151ab4bc119949eaddb2fb85d6c30db49e1312f9e0a5434645d3c3833096212f704cf1a545c76feed6fbccecc335b88863a3ad7c45fac155cc75bae22151fc7ba51b4fbbc78deb4b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e083bab10938a8f7f8c5781e4630a309459b8cf389e7c5fb97b24ae4d96647690b78fdcc3a4156bb62842143ef7ed2b35b8ebad586f6c807c3b0884439ddc98151fc7ca61b4fbbc775374000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002507e1990cd47eaf4a318efa0c049095ff245f07d9a6979f82f9a811fd07062f2108d4a7b62565675488d581c9178f2bf00483d278f4b767af59bb98a7099aa7d51fc7cce1b4fbbc78e601b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014e0ce98cfe312272a45ecd3de74b254c4568eaf6be43593d52565f5931f0664631d0524ac8156904405427119d57b8f1aed9e88cc6d5caf66821596d9d7c380c51fc7dc21b4fbbc7acc55855000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000295c47a1bedd301a0e668520c0bc4801e548ba675e5e7acec5da5656872041374586e1007b25f47c4c86cdbdfdb88e3458a29177f3e305934fb27b02f0a136c0e51fc7e211b4fbbc7e7f15b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b7fb58ee4522295549c4ea9a1819278184a27837a090de39916c0a2d4a8b5a30a7c4a9e1cfbbaae214e02e835907d1ec001f35388d3b9ce9b71a8272c39e5ede51fc7e371b4fbbc7e47b8600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000240ad5f3b6800a881cb6e68b39f8e9f81531f9e268d19f02707be1ff7d4576b8f17ab82c5ab0c0915d4f70e8c33a062a35d557978962a8de8ed06e9c6baa094f851fc7f351b4fbbc70e0e8a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b802ad8efeb75f18b6efeab05c117d64447f666de8bc145f2eee71363129fa0fea584e297e90bb6cf6084943e20c8088d2d302e9978333b75b23b9cd3ea0197a51fc803c1b4fbbc792c10700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020d11cfba3b7fc62b1009e716e1444b8e30d61a07b4e55b8087bc648f6fede3bed41bc6c2f033dcc09c77daea641fca49e2f1ef764064cc94bc13d04b3f69f25151fc80e71b4fbbc7216d3400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025448321a6a3f9f8282daddcce74b46650a0b43c4e64b3006bacb87b410a29d9223acc3a6771163aafb7768064ac19925c03b1f15bf1f097b6e2f39fb1ef85a4551fc81331b4fbbc7b6d30180000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a125356d2d75b5a9baac0575fa57510c75641da123d3527700f847d2ccc0cd178ae18677194a72fe628c8c9ce396d807702ce17202fc5751b5e64e5339ba121751fc81621b4fbbc762365a95000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e7238d7c57c5b1c9e188a1e071c5ef7a0b2e1a3576733c16c1c629399dd779a696c406a23c31faf0d0754afe397d3f74add1cb90b0ad9949cc8a83cab856d50b51fc81cd1b4fbbc78a6eec00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029cdfcb24f7277a275af68bbf468f051fbc6a192c0bc4f0bc5c29dbf2ea1a79c847dec72fcd63bd77daf3439f9b5da23ef9a3da8751f58b455a64888a0373f79d51fc821a1b4fbbc7c76b0080000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002756cfcbebe72754c931ed023af7d43aba9b2ac4df0ebfe8677170a39ddaaaf275c4227e672162fdb9795ef23857d5e0fcf9ddb5b25930510c7c6d1be6ef131b151fc82431b4fbbc73a779c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ffc508b9e27c6d20834ddf3b6a434c239a38e7ebe194ac934b6d3d701bb6a549d7c44a09e46a5d7d8e0b27a1b1bc61bb9dba51a2fc30b8d768165008216dc75e51fc82c51b4fbbc7deba0c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002644c97566674304b843267b096c567d15aa6e713e412ae9c6c640e0dd70d64c41a18acd13ab3256bf2e99f2851ffc8f6cbf53c120f24d827cff3178b68b5c2ba51fc83921b4fbbc7a3cd7b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e1a4f5902c298ffe8f9339d458af8d103affda74126365e95c91513d451b4f98fa92a6ffff692aa78ef7290a3f28544c7dfa522e36f50884b6cf81551f8f96b751fc83be1b4fbbc7a3922700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002638c9ced1d2842a4df47093938e52a8facbdf5060987ab66912fbaea58bf4e2f72ab9ee4d7425e958fdb75abd8a3e54e19f8ea9a32934c769262e033bef6896b51fc84051b4fbbc790d56200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002519c4a8601c520cc854dfb80f68dab32b0c8973fd836d87f1ecfd39f0534943aa22ac55e1f7d2dbfde05f866a5f16ad652d3dd6689752b80c69d7bb80e3ce14b51fc84961b4fbbc719ce0e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e727c12eb54705a8be739a214c80e6689e6cb2926ed854e0003ef5fc7af163cbb1f733d4236ce6052a1ea3098fa4ce969fde5896517971258928020f2cdef51f51fc849b1b4fbbc77037af00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000205a02ee21e4705b112542874e1e3eac43a524e954b2151296ec5c26e9b98424ca708c572281d0cbbcab3183701937943d98af9b0d3fc54f2e9c470db4ee6c67f51fc85ec1b4fbbc7d0471300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ea13c8dec79ff68741f79e4810e2a3d36ef23dc82101f03d9cad88a5505e4d02c51eb34e23e2afb07cfdf1a1dee46de61f1bda95a656f637c27133928091de3651fc86831b4fbbc7b615c000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020f873fcd7128d947f0c04e1c2064fd447f1a88cb47c1796e2433c2455606f9c81810ff35e0e9b7cfc161ff52507c11ee1637afd68926c20e793db125308b2ec951fc871c1b4fbbc7d6e7ac0a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a41de61b9007151bbbe8172cf4f1ddbba12a91233b0dcb18e3a4cc891dd571ccd90fd6610a68852c891bf67d6ed51a94cec90e6b02917948e5bc1c06cc8bb51851fc87441b4fbbc7956ca700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000280223323bb6bdc654f92d4d13862ca954d5460890bc0d272d7a662e5528a8d1d43eab544f549ecba88102934c6f34aecdabc79a66d9e862f088255cce343f6b651fc89471b4fbbc7cfd4e400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000235700ee16b8a4d3ff058fc448563f94e70c5ce0c57933c7aa6af1053c3b7bea2862cf971653ff68afb0e9f44b6f045bf057d44b682d0c57c5066a52636f1f83151fc89ec1b4fbbc7c5f49f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000200f7f31baa109fc73f9b413883aedecd280a0804af828f7e602518029ecd45afe93219c5f8c1e82b5526ddc419c57e595691fdea3fb6edad4dfcd59d9c0760a251fc8aec1b4fbbc7d6942600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000247ba26062a7ea79f8d52c9c97b99eb4dfb1da302ba2a908a82be0636d0942c1f0cd7be1529edcba349decd36dcfa65335a1d5a588051f4ff4001a904ed46398c51fc8b681b4fbbc788ca0500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002becf0c9d7e21b9c0bb550e633b6c66aca849ae7fd33a0f628a395c9ce91ef31691405ed0440c75e953a44b6911430c5b08c8978736a5abb507fcf9ece64d67b451fc8cb61b4fbbc717ff0100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000251ce7dd3bb6bf5c6caff59628a98ba362ffc075fdc9bbc59e6277a88bb82a4a142e20571db9332b71b11ace5ea74a6b44a33b83ebea8ca7aec29b811f692f0cd51fc8cd41b4fbbc74b79a700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ccc1e79d0cd067d0c5cf5dd126f85d870ba3f256e908eb83cd387646f769c2e0528dee316d103c32dbe6553ab020d157f096439afed71df10a91df987a61a2ca51fc8dcd1b4fbbc7d3c41ca0000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001bc5b92dfa95da7e41f24b2c8472b4b79dcb13a996c11d91b47550d1e6e78a1ed87854a2dc9d3abcbbe80df02af04628024ca719199c5371505e637e12ccb849c51fc8fab1b4fbbc75dde7e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000222f52a66ace732c9efe5f0cf226bbd745addebcb43671c743bbbe1a2887aa7d0a9efcb5af97ddb8f145ac61678b8c26f5da382d311fee3b4c7bf932fc6ea187451fc90141b4fbbc722610240000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ee65d370208182a2aa2fcf280e7450a17e4fc60f4dab48261eedb5a3545da06aaa99eb907d25c489dee211b401697104a31fe7185508ea18e106418456546bdf51fc904b1b4fbbc72fb6c000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012c6b13fdab522f87569ad7795e0dc28df656e513d31e988dd19ec4bd5687ec8bed0ff61f6192fbb4118f81894d90342da4cbfc60d258a06c4b6bdc376aed92fa51fc904d1b4fbbc734572700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cfc41dbfa8de9aae7792e5ee2d7bb98d0b79e90efd45079c6634f56cf3b3ab916559e76b7bd698b2c72011aad38c6af696c5f80f98cd6977e95f5593984e87cf51fc90f61b4fbbc7b6f41500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021a31b4316d8fa14e0ee20fae775758b52eb661d43a4911f0db7310f3c20eaac4a58022b98d50974bb88b91b1ca4ee6798a225f816d5825ecd3c3390f04cc21f351fc91ec1b4fbbc7906fee00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000171c82d31047938487a888b0df2a98ab459320363d02f4eaa1dbd3cea4bd2646c3a781cda390176b6d9747cde77d337acfbcd5d0392ace8a1abd71d0441c43f1451fc91f21b4fbbc766060340000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000269e76c0c4eb0c9663a205fdd44399f6b4a238044cbc13716dcbe56e08d17eb86296aa9c21dcf2d8e6f5cb2ee4926757d83d9be30079de96f05bf9939e460fe0d51fc92011b4fbbc7698c5400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001eca525a85af98d93157bd41cef5e479f125f53574f02ca33ae30c2dfc957c17cbd63a17775c323cdb0f4856e92c94e0accb01c57c12a58045579ea6a7aac323751fc92961b4fbbc7a6840001000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015c7453897a56a17cf2191be64e0eb94721970971b34e0d2d3fa356986850e30a3c2c9d63c34fa44afd8d9b5209a5b4c2e32cc1844c51c69b0b75ef2b0864a7f651fc93df1b4fbbc723639f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027a42cb8944ac5f4d4c4a08d3d62d0f62fb18fd9251a923f2100661f4824e6e7ad114441edceb4668c5940791a5a08da43b9fa270a9675942d5923d6e42af3e1751fc95ec1b4fbbc7b4be0b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000266639a0c6c2f7120f4b8de1f2963cd4d946c7f4827609d8f70c8371c9ef18dceb4c809903a7c3fc2a857a9336fbc0e7d5c6f214cb3c58849a68fb64aa05dd5e751fc95a61b4fbbc7b1dcf700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a12188b7ba3a42fcb4fd2ee39250828fb1daa0b7b1800983245c33359f3eab998e537b78e097380807ba5cd378bea0998ab5be6c443b72d53a09c7f4f9b23d7251fc95a51b4fbbc7e7410100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010a00c8cca67ebd61a2a7e9ee83ce942ea6ae1396ff017dbf81c2fcd84b34ea9b052832468efabb1f0f0221cc49be870f04f94b496bcedbf4d3826875e5ff950251fc967c1b4fbbc7cb54c100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001da7919c9aa3bd71c57704ab9bd451770648151b123130723baec9f714afa3f15866c3e1a00b3d93cb41d637c96d9b524a65b4e2338bd85b780b360fd0a8db40351fc97731b4fbbc78a361200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000283a028991986fc9063f5c711a4870fac784556ffc96d2febb6733e259c77e3579e32c0f5303b612887c83529398ddcd0e1162ba9e6dcc0c8f63f2197ff23b19151fc97be1b4fbbc70340b200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000221166d72524b4df2be60237467fccb098345e826c8de6daa45f5c938607067893797f9ff5efd4fb5c114f6a85581ac55323f62c58fc5d711026896afb77a67d151fc974e1b4fbbc7a980df00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011b4b7e8af2261145beb1c08d5e1b9f54e0656efecdc40204d82f3feeb2f7f97691ce3654716f7022c39e1de66c25b1414990146072de55f9f219ec8d7480a35f51fc97e51b4fbbc772b5e901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026779df0fe76902b73655f00a7b3ec75491efc96aa5e38ec2ff613d9307656dc5267ee983ba21905966b6262fe7c2b559705e88dfae7c678f1aa408440945d44551fc985d1b4fbbc7e3e34c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ce25ffbf6c673ab9e53751a6c48126c19049b93eb068bfce6d89324bd302ecec7d60cd85291156f106a91ab361b6a2bc0cb1b73b3d8f10c815586dcd9765fe9651fc98de1b4fbbc7d29e3100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e62159983e555b97d03852baacf13673201d452acccb9cb2b822b07339cc76cd54eeb296580a466a438aa3561da752fe85d22fc79eaf4fca71fc85f7a9eb757151fc9a0d1b4fbbc71b6ba401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001eb200df1bcbc855209c57203bcbdb06138374ebdf9af1249fc5157473326f218d860bb22a02c3c59659d8786f51ac7416704499332489f94de3b0d18823fa0d351fc9b381b4fbbc795431a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000141f50fa90ab34ff65b09cb11200700edcd8f619a15ef6c20cbc6786d90d0dbccac915108cd0e01355777169ac84c1347c528bae20394acff777e33aa8f60967651fc9b4d1b4fbbc7ad710400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010394a7683d9e81e9e862d354f6c9c70bef2ad8e4c87c4dbbae9005a423d5751ea864add5d6747a3c991f2b687cef98114657a1c02c6f7beb21a8e6e0346e10c751fc9b8a1b4fbbc790b7b400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000177aed046c1a61ba27c5bddcbfda32df49b735cc01fc3e5a0b0ae44f6e13ffc1f1a0457b4a629c9a89cc7740b01c9d4b039b4d68dbcbc3b4e5549c6c6517bac3751fc9bb11b4fbbc7ba45c500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028d8f27c8db49583731fbb2aac4a0b86c4560289624c384d3773a3b49100c2b9f7fe1ba036601a365a6cbcd9e7d4010638219df7bd7434a907c7da1369ef6947151fc9c301b4fbbc7f4d22f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a550d723047d80a6effa871afa9560a59518addbd39429acb247e2dafcdbdbe7d46a0e5fbe86c3136ac4d942604e359aff0874ab78b355aeff9fb65ae6f416bb51fc9cdf1b4fbbc746e3a201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cbc3296d373471bcb0ebc45c10729e9ca0f416c80fb9b2da3886aaa7f0fd969205b10020bb76c00b8cb535127625f2c38fb9d7c405a5be6034f3d7edd86f6d9251fc9da21b4fbbc7ab3f7400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025a3cd8a44aec0320e8a2e8130ac70506766e6beaaf52b8835a0e5908fac7bf8e645b67fd47b8e68e38b20b8bd20913816934e01bb28703e07bd4e6e1f6ef428c51fc9ecc1b4fbbc7a5a9abca000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e551ad846ef5015e619f0c9d363e75ff5059b83056bf949c527584b1955abcd1cbca131ab89b9c9663a38753b320e1d87aa500bcf83a5bb20ce73f659a571b4a51fc9f121b4fbbc7fa800d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000181dbd4591f72f89f83c0151a5d10d4f9887da270df126b0b2140c06999623b092660a4ae9729fd303bd55b524ea533c640a0c8be74039348dbcb312a26f8bd8351fc9f731b4fbbc73e8e5b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ce6555e6762ced2850abef75c64c6ef5398ce076c28eae59434ec0d4e8c3be04bfbcee53749960190f0ee5facd1155839aa4be506b53675cac65f75e5eba77d951fc9f541b4fbbc711449b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fd1ce397d07f750556a3485558b9ea7d5b6d98b8d8c9f4d5ace7f5e344374647cb117ba19d089e31fea34d855dd71d622ead10556a9397c4429edcdc37f265c251fc9fde1b4fbbc7956eed00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027ae8e728cb97e00f7c478c34213eccd9c27e68d46efffb450464d246cf8a20c568bdc09317e3a1045879d07ef4cfc8f0ff5291889cda92e62d48861554fa76cd51fca04a1b4fbbc7b1774f01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000235dc27489d90c1bdca4cc7f96e3e4c1144675e0f4f317484d7be86789e02c42b35000b59b9708c4f5d553df19421c4d8a1c5781283077f92ab42b7f9ad66bc4351fca2141b4fbbc7f96e0700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000219e9a4d57553721d5fcba135587511361151d7680021820d2b4df9001bcc2c74705640fe92076d60f6de2dc959716408269baf69c1b73c1e5fa6d5ade2fcebf951fca2e11b4fbbc711012500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002da79a1c24fd0f52b9a36769e59d830467c06215272c7c8a538be124106565ed094d4927afdd66d13799cd5a8fc4ccc57845130dec24360ca46f7ef1d0294003151fca3241b4fbbc73fa00600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025e1d5b35f45cae1f7e7730210dd069f5935503a831d91c0465df861e32e87f31ef5c5b7e85ca768ffa8575eaab5f2b39df185b5d5265c1863c905eee2ea407ef51fca3aa1b4fbbc793e8cc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ee19b2823f9f3e408ccc55ed951eff22c9e476de5042ab8d2b9161c89081e42c0edae9f72d1dc213dde5d4253264c3cb5b87a2ce74dbec2b45bc1c784ce5ac2951fca5c81b4fbbc75d41ed00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000289d3a86485773733e814102742db9340b860d13e3593895792f25cbef2b6e594d7c41e4bd30f288718220bdb65fa6aab0c092fe7dbd9ce62701521c2f97091a651fca76e1b4fbbc7728a7200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e86473e92246f6798cea8810e4f5a1959df68339e589417db45ceceb601058127aa06c40c08428f753a15dac808034f998b537d1e9e8ca28cde4cf188ec38fd351fca7681b4fbbc7c0510140000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000217c3feb32a5ae001cb0c1395faf06f2605dd1ef28ac4b527deccb463b2d13d7c87c9680498d24fead17130b8d438929994a01b19434cdd27e69f524c919d6b2d51fca7a91b4fbbc710c13200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021cd9d371c0ef7b06ac9f3d69f4e4b150cec27440dfaf20e0ca8190ee197b2dbf691f8fe9b46f7cf0c771830096f71ee4061219cb3d5ea726d595030cfdf551b951fca8571b4fbbc7c0991800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000161412dbe84aedeb75dcf9db47d1f080abe534714febb380b263735a644c9c6841d765a4bb5aa4254b2108ce66634abf6a0c750cebfec70cf47374c9b067c132e51fcaa4a1b4fbbc751c6f401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bfd64cd65c46261329ba4b14a72e001358b07fefc0aabf4981077fef0209b6d01feb27dc6723d2013852380fa8687d0c27fc03100517ba81533c540e433a503f51fcab221b4fbbc779cd1f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000255c3ef37c135f5cdcdb161709d7a791dfaa1e1a6f496a62952950c10a2c0a1940c04b56829e4e91bb5ffd4191d37c411a44fbfd10dfe7db9d65963237af2786d51fcab3f1b4fbbc7f8c94401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027f66fb01b77f0e9144daa0723cdbc85f41de3621095c9cd52b6c28e349b4e33ffa8672292bbc071013f72b52c8d673d57b5adb0ba476a938760978e063aca54c51fcacfc1b4fbbc7e0e47a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010879e84c532159330d9e40cc35fda2cae96f9d9143b0e0f8b96921776a6bfb7e1e7df3f4aaf0e7d420c8458491b7ec2504179f7a0db0de96b576588d2060ccea51fcad431b4fbbc7ba4bd400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001eb55e63b2410d32d48c80ff46520c2372e402c15cb8bd28d2e0e8768740bf4119d3c8d0570ca107d2e39059c78bcf7320a9fbb56ee0f82b91479f927e1c690a651fcae1a1b4fbbc7c3adda00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a052ae827080befb7ea4c7ad8b4f307bbbab6bdbbbf6bf86689d004198b94684959f051b96bd63d0460ef32e47645f1d3f363273b6b57f3267d83b0b004d311e51fcade51b4fbbc797822500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012bb8a93109061d2664e225636eff993a53df921558e6f471b492e07745d1e6d71fa20207115d18d9d4df5388cebd37249ce2337e965a288b7cfbfe5c9106130251fcae631b4fbbc7663ca100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001377181a3e7e9a5304f9edaae4e778f2b7093b55b50c09b3e9e2c058da97db24b122d1725d4be2ae23995f492bd7a06b735770f0b37b89747ca1aa514f536e96b51fcae9d1b4fbbc742e80100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024fc81f38459f98af3c268bb3709c8595a07045ad566f4e8f29e740619363aae6815fa543f5deb97c887c8d11987b35a0cb1060e117b6b43a43b3a5adead2d6e051fcaedd1b4fbbc788451f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022ca85f51840e289d9382185076838f6f5f264c0bafe6618f64a0e1c2be8b31c7a966a8a47512ccecb8393141477ad4ec4db61b568aaae800dfc0767dfa688ab751fcb02d1b4fbbc78d538401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bb97f6d1c0243e525c36cb0b6a3bfb76356b6845e543c9a27f8dd0c2a3f0d41176da2903e59cb29df9af25b484275f83e90664820f12ba0d9b092ebf0bcd149851fcb05b1b4fbbc764d27500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029ded53c945ca95a2d25e23da6e7ff092dd6ded3f49a0934b633aec9ac7ab172c5d597ac1dedc60ead6496c141d6f2de8673ff6dbf134b7b25c84ce7dd034b0ee51fcb0721b4fbbc7838fac4a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023b1a1b1f4cbd5975896798372bcee4e5e8b03cdef0e4cc1d0cfd8eb1122ee4cbb42c48c2e0c0c55a90d2c72dfebe882938b0f4038301f76e4aa7f2e719fc3e3051fcb16d1b4fbbc7261de100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001b77b84293869b3638c893c78f2329167c4f1d6f8af19e4ff2df8caa4dc450ef0e2c1886b05da9f1ea26c283fa3d357baa5827be62e2f5f8ca220a4334f48f93951fcb2ff1b4fbbc7f6e90000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002756f4e98641ffb92573efb1885eedbc40fbe80eecb5164e3a47bb1354c030f1e9c04c5fe9f65e4158e199236e3587cf1c7f6df8bf26b7675e44afb806b6b021951fcb33b1b4fbbc76f211701000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002aef7bfe8d7699952c0fa2a1560234e9d207dc37fa64f14c0569d11f78bb54d30b2eeddf8e85c0faaffc1ad60a35cf31276f8500469652190d6d84f58beb3df5751fcb36b1b4fbbc726df5a35000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002094de5a0512a04767295d98047dd6d999e41c0a4177f35df705a9176d04580d72a3341c2ecddcd1b8773c2b6c2e5c2bb659bbd158837bd5c28b086851243496e51fcb4371b4fbbc7c5e28200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029c9f9c42e1a2693c08fda9f897c5c3d332b485df3b3f63f4194ab9d1d432ddf7c97f1fa2875583a4949ab810af09c53eb52dac084002b533823f28055effa68b51fcb4381b4fbbc753910580000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000194317ca748953fa2da2bcc5d95098d8c6bb3fcc8b0fb71e73ff9cbffacee98f6442de0718397decfdb22480fc33c028abeda58e80dc872c37e47ad71e87935f351fcb45d1b4fbbc7fa072200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012ebdd162bbd48462b56533cdd9b8de5da48e0b8db636ddd9fb3b1a8070fc0a43bc04c0d16baf35f1c6105e5ff11fd57225c4c02398799c5666cac218f664a31951fcb4901b4fbbc7bb4a0d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010538e322583324d274de98897fe92652a04214f6fa6e3f8737ca836fda188e207bdf72726db201b70501cd568549022efd0509555aa6a7392749f27e598432e251fcb4941b4fbbc72dfb6900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023bfd09aca44d88955c3634f8c42598e3ebff2800d629fb9fea7427ce254addb9562a33e257bf905e26520c3bd8042d4199b1ad4250d4423d1d9e87df44fb797b51fcb55d1b4fbbc7bb3e5200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013911a66bbc9c59615565f73a18d70c002ad5cb8cf9d0ea3fdd3b56748ba93ab1b85adaf9a216d51ada714349b1252fa34a77c06aa1a1217fdb4036242bdb04bf51fcb66c1b4fbbc7b47e2700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021b2c33a4453918bfdccc9969b3084c349f9d84faee4c22ec98fe4a3b5cc7998b6506ca3ff81c37a0611f1bb7457e88f03f787b02db0d0a7a26c58160341b544c51fcb6b81b4fbbc7ad974200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023c8468c54fab6122206a4647966103e3e3025b3a79b140a5aa643cae6dcfe974fb535f74ea01c399ac3e41b887276a9c534705ed805151b13c489a67536a66a551fcb7001b4fbbc762bdb000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f441636957eba8cca1d97f79f9e67b0db5e75304953e75062da3e9535017a5da18fd8b941b2498e22c0549dca5137de09695e8dc1eb70dd2301d1544e27ac06051fcb7351b4fbbc7deb13301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012968095c61cf8d023c94686571aa691ee886caa2042c004d0c5c7677ec22a2452f513fbec172be3ca939258245f25e24488ad12f0d8b0aebfd1d2371dcc4242f51fcb7e01b4fbbc77f250c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c4a5454be7385e5066a8e698148eca120a2ac61e9e67d3df6a84ce75b44908133936cf1d68860364c06bca1225f1dc9d8ed8a2e7a0a1aa12eda6812fb949e04951fcb7e71b4fbbc763ad3300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d278da3ddba684fb813c6ecf881ea01484e4591c01ad589a8173ec1eb49f486a5cfa37819bb8802b60b3b065ddcc3d6901e1e135414ccdc54dbf2fa64b2c83d951fcb87f1b4fbbc7dea11a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001da2016c9bcae760ddc63c00bec8b3d9a51986a96478d4cf6b0da321e56512f17e873aea48f9015476d9c670b6e1005fb449d4c4155dbd040591322b76bf5b15651fcb8d41b4fbbc7ad20cdcc000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002120b578831341f2a33ee966cf690ad9799afdfddf43903382a1403a61bbe249d1b5cbab689eedb0d58edf03bbe415b623a6c95d3c8b84dc6eda45b83d85004cd51fcb9511b4fbbc7ab680b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023e0f57493745d100eb732fe671d727cf6bd5ee5fd31408baa495ab97b0f88e95ce98fa3642136b46dc181ba36ab4270db027da719a886cf0ee0b0644f0e6b0b751fcb98e1b4fbbc703f600c0000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001395f429e1ec7603e7a9535768eaf27cf0fe953bf459433f69f2667fac8e2200508bcc9397c8dd718d0823f303f7e9e401c9a8376954336e767e277987dcbaab151fcb9a81b4fbbc738fc3500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029e518ae36fe75140e858f3749ed337f42df1aba0306770b9435bdcb56acfcb502ff467be0f35b2a4e0da65936cd071348627fee539e675796927884da9e50eca51fcb9f21b4fbbc7dca98100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000249503740fc56221899f2751798525ed5983311fb5e3bffb7d3371841fbc7fc5fa20632e05d6c95f51c4207c079ff1d00dc74785721c94aa73d71e5ef1a51b08251fcba381b4fbbc7884a1f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026f4dd12cde843fa6ac99e60469bbef1e8a787de0245b4066d595b016f7073e1ba4fb79842c0daf2c49a090248c0748eca85af9cd99a1944ba32d1a346910704a51fcbae51b4fbbc718126b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001700d6d951cfd179e5f339114abca7cf1dbdea599a114dc32c088a0bf318e9921c2a69c9dc2522f16f4c69bacaf0e44b6de1fe509d4e747328d780e233c6caddd51fcbb3e1b4fbbc73651ce01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fa8493441a91b05b6e5f91d006668b1802364b47b2b7bc5e564d2ae900298a571526d66d3ef2e5ddce6bddde920f4905c1312213e9de880acf2f5070efd020e851fcbb721b4fbbc71f0b0e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a4057bab7f50871d72f5c7a441cf8fd473bb471c290ff193624809055ddee9a7729b1f10aac92f90a575431b82a0f498871a5a258c84f87f32458c9a440b59d351fcbcc31b4fbbc7f9b93900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a1fbd5d6ce084424f5bee4446f06bcc703a88adb151c48c55bf363b2b745cac54b50241dfe308bd1a2778b7050608d714809d4fa47d7e8d1391834dfa8bdcad351fcbc8d1b4fbbc7fcf36a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025c3c0c5cb1d3a10713ba17eaf1cfe875f15b1ba9a536cf4ab1cc39999254f18f166d2ee7da3c64f49941dcf9aa526a22a845a28f0fb10c1e1d75f70a5c8d352451fcbd3a1b4fbbc7c9b24a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000138893baf9ad633979b90befba7fba55d220bd0f9fbb81c822620b5b68f22209268fbd4d6ffa94b99004458257443be3dfd1393d0762f4d5406583a4270a6144c51fcbd461b4fbbc7b8b85100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023d27328ffdf444ef7a36eb6ff151dae4cd08828abf134454bcb30d065789cc668c2c83ecba6627274236c712fda3c4173ca9e1c171e271bd678ef308491a8b6f51fcbed91b4fbbc7d82f8b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000189bac62bb1ab460713d849d42fdd3a049172dd7afd5123c7d5f20a7df334b9a602bf0db1a36bfb6802f1bcd7529a0392513edeae944ccdc44d5ee4840d1f28a551fcbeef1b4fbbc70d010100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002457674ba5525a7734ce9bef4ab0c789165df9172e6b1a9146dac0f72ed405adb83979b7df037975fd0bd2c2671d95fee0b17907afe4a760092017c164b47e94a51fcbfd81b4fbbc7f52c9300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001694b2f296e22e2bf002b9005765d54c298d3c5fc23248bd6793244cec0e0957dd282f36dcea2a33f9c6bc2c5401421c1c6ce93357eff642fbaf31b0bf2b98cb751fcc0271b4fbbc765e31700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011f72202b5acf9b61d5b6464761265a4eeecde35486278012e5c29d6d316eca067afa5c03d70d5f894045c01e79f47950a2dc53f05ef99abc176d1575416c4ea051fcc0371b4fbbc7ad477c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002572a650e809e438a61f4657dbaaac41e594347797318f1f5b0301b0bd4e9e26f36af675449ee23402f0cb0cb9dc8f9ca6f67d13b5847c248deb9ca0bdd06a6bb51fcc0d61b4fbbc708857d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cb60031ae6ea349dfa90b17399e4eecd2f10a760ee7829b26c467b3d8ddd18db1178dafccabcee74437168dbf1de015e855fdba9976a4a61504eb71673275bc951fcc0fd1b4fbbc71a929800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c912b22e17fb9b4b84e8e110a0731fc569b0e561280a6b32d1a46ce5e016791104779162ac49ad13ca3b74bc73f4545db19b32547d4bf4517b747afcf2130e2a51fcc1931b4fbbc74cc79a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026e8be6336e00a30cd978f4db661783d8d83029ffc89a8095bf8572508bbebed4ce854a7bbc02a45ad60896f57c9af36a3a5af3d4a008c5f06136f08739f5ca6551fcc2831b4fbbc70795a800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a9fd8aa374d1bc3fe7be1f9d20dd2fb92cdef4817b546c90bd2d7e72eea46418ccb4be94e0d7f74f08dec00d64a8fd599b470658bc507a563fb02fd56102ac5051fcc3491b4fbbc76c472100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029e741576242fc8c9819083717d619bd4edccdcdfd2b8b1ec14130e118458768d76b4876ae75afc141d15f657a9fd616d420fc8c8c3114b776115ffb98264617051fcc4191b4fbbc745d26b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001af21b6f214b47bd5c04669f8ef15abb27969846e039c28f7f4a4a81a20e503150b8435ed13e0976f7680eb3b40418290403c10b5ede98f63b00e6681f8089bea51fcc62a1b4fbbc792d5b600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f5ba7bb3d862a7ca2145c36c8b84742f3e31e703cf2c67b9b4b2b595a26f9a072e57213106b5d33359ea06c473246dbfaa94bf2a7775547ea78b7c67d593971b51fcc6891b4fbbc75ef11702000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025e04822269c3e74e76bf62dcb636c76a198628bfa9891859698f7848ff8e01b41808a001c93f423c34c3febb6134beb982a2923efc5573887ec4fd15bcbf04bb51fcc7011b4fbbc767a89d99000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027e6b60e52fc4ac3ec8ea7123a14e25bee7762e950dfb55c31881bf80e01f324024fce25563c76fa8bbdbac92a40d598063b207edd6db130d5d9ed3a79cec38e451fcca081b4fbbc7f2e258f5000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020f9d77e5c2a7d347cc771d93372b3d959e3ef0a863481e7e5888d991bbc122b0358a632b28a96b23aed181731bacb99cd634ab01045f29c921bae7b54ae38c1151fcc9e11b4fbbc722940000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002de23fbd9f84aab4797ce957012eab56b7321f0ebb88fcec2350c44698ab6ac274eb6642c27c4a28be9160250c086238fb2b07b55a6c43fda0a4d9ad868ca6b7a51fccabd1b4fbbc7f5227b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c2dc166bd4408345ba8bed8fb0e0400abf5ebbfa847faed235b10134993102c6e076178c9f7bd794c26d2911f1dcd1524e52618115c1428a1efca84c982d386151fccb3d1b4fbbc7ee16adea000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000261218e5613e7dd472152a9e3e8dedb1022c55a2184c5c555db03e8f6098aacb9b89cd9959d523851f3b0c874b66b97071d451f16af27c66dfd3f9a38978e373051fccc5e1b4fbbc7fba69700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011be61e4f95bb13299adc9cae3f5ce9a376db25ef4a273c6e28e60a109acda63bb491dca6ff8e88f0f7597f7592ef1aefa3830c0284b21cf9e4fa50af90eec2de51fccd091b4fbbc7cb6c3b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022201d622712c14b48e97499df80e98a4017f5f51f7b722956496391acfd182d540927a7caf82bb76a90b72a1885029b7c5439a19766a6b7ff0c72ca88ba4335551fccce11b4fbbc748893b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002646e84d88c1f0358bfb213547f5f93078940f5308bd1b0b5f5ce07efc06841df62880e941ba722c1a261e6079b14a57c68f172edeaaa92b501e27913348acbd851fccd3b1b4fbbc7dd286300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e10e180b4c2fe83b69ad0a055a3b8c738ea32687aa613b0c92c08978e60130f1bebcd946d3c457b4d7ce0ccd78354a4307798289bbe289ece06288c9711bddeb51fccdc51b4fbbc72f1d0401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000112ecb555b7600d3063621fa7c015a7e1b1931e409f71d08320bf0d98f17049ac2eae6b39c5a78879d1694e7c80fee748de046b3ee34a6134dffa098fad41615251fccea11b4fbbc7f18a3600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024297f28a7bd4118e0f056b7b12d1632489478c0ff7c9b525cbb8f248764d567f83c0421bc737768d7b5d059ed3aa9fdaefeebe9ffa41394a20170f226c419a7251fcceda1b4fbbc7fa372300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013a3ca9f1b0bda4beee1e85ae6421754c3543d626eeb7580a3da280fc6f8a6f714d58c6ba4bdf26a385e8f00484345c97f51addae18097c55bafb363d92232c1e51fcd0d41b4fbbc7c4884400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000157cc2b1cad0b3227e54469992f858c9b37e9f84b0eae8b28e166695f68ec07a88e13768adf054a2c3e20a3921c6eed1f777c69e8dc0b0569d4516550af52acd451fcd0df1b4fbbc719eba100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ca39129141026ab4e56a99ecc713ecee4cd45ce345d595c6adc7ee983daef5ec4181189c0ac540d9a88b4e13f5b3597c8f0306ef153e7ce26bd65354e08341dc51fcd3c31b4fbbc7c57e9f01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012fcf704ee756ea944a1e52df5639b2c7662a40e99881c08f8fa931d37fcd05a62cff795c923f61174394f3fb89db54a512bad74461383a1101688778968d110651fcd3da1b4fbbc712c70701000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000251c962d5d8bfa43cf74dee502595ce25d72b36cd9eae92b6e84dfd9ccab053db52976f02d97c43916c0602c3560dc76250600a8a7dd01fdfc865c0364bccb2e251fcd4aa1b4fbbc742285800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002aa11a2c9a9cfa8990591da20a62ea2bfd819e354a6df2ed495389d7a338159201fd25867d54e902bb5818b44795f77563da2a7f7a2941f9386c66e0835efc57b51fcd5e51b4fbbc7edb73300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025fbc1c85c289928457ec86c01776020e773f422188e619647af4eda0f7d7633f5e63647051e8112fe5a7cc3a196aadd94c596533f4c2ef28c7809204471015d751fcd7b21b4fbbc7a5a75500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029990db9572ee3d1bb8e9c16b586f40e611aa02b92a488550f921e8fc73192edc5453dc95cd89f8d8c1dc47ffd15d67699582c406577d2c89afda606f18073ec151fcd86b1b4fbbc77f380a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024f706ada73d7130f89f148f3dacd761922868858f9d34250c597602756f48e3d4e3f1ddfc950eaaa9e147beb1224041e3e95e0718d0c0a2017e2339046a0227a51fcd8751b4fbbc7e5eec300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000223d1ad89e7e8d323d4acd5c79a61d9c8b6ca18925f3ef5c8e748d6d81a4179c799254af020135fef65493935bd66953f09a0bec595d3dda5e67ced5f165baf3551fcd8881b4fbbc71fa72601000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001977f5a3de6453dec594b78723b2f74fcd12356223bef5dc3bc035f9fd92f6f553c4dcf5ffbaf8db8adcad8b07a5418f80e83b5eb0c8e44a557d720160141522651fcd8c01b4fbbc792f03800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021dd94dfea8c82b0c7a5a6f70b9b705881ae9f6efcce33147f3ffff8b178cffc3109ff1b6703edd1d3870c63be9135ca09d29774a185519397dee9cd007945ce451fcd8cf1b4fbbc77fad0500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001eed3599d9dde49cc01dee2759f0e4db9e47831c6592d92273632f927cb9ed2fe6788e0d51b056c2b3f9d62897947709d879c9935241894cd503eab8e4e2b516951fcd9111b4fbbc7303b8001000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025c314ba1e975bce875dea75539fa666f55e5cc413f09088470d212944796377f1b47f1b683480b92b8084505825cdb98a932b67cb12fb41fd9dbf7cd69cf673e51fcd9d01b4fbbc737557d01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016ed9398b52f0518dfa08bf0fc0e19cb8aa9d1f8cca7ce5bf8b83e28f95da02ef95adacb1280347c9310f69aff0e29a7b0eac525319b19cda9e6b123f2bd66d2851fcda041b4fbbc73f694e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001615c05f99364910225a56ecabbc205e5665a844933c9ee30fe43bcb759c421bd0d65fe3ddbcd1a1ae2219b60a5b63fb5dd5a55481cd496cf1b8bd808f0a46a2251fcda8e1b4fbbc7e87c5901000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d20b6f93200160a6b52b1ee5a00e13693f0755ab0918a3261b00a177345bc7db220517db06fda5df7d8d2f358f094e045022b5497cdb92d550999400761dd17151fcdc761b4fbbc756645300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e9a8235307ae9c911cf9065f0dc9e47529a9cedfc0160f5fe14a5e32ce61a9a59cf9965ad95e5ace8b46ba354e1dd50f84f7293aed011c820e1d6679cc31b4eb51fcdca71b4fbbc726061c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022ea12d442b623ca2472428512538213224f6c51e32ee779fdc24435d1e3c0f19c037fe562412efc4751b75515f91b2fcf527c69e772430a0d04f04c72c9e788851fcdd211b4fbbc733d02e01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002eaeef4dfa0ef2114e9addbd64c79619f712e8ddb4716d7b344e026ec47d56a7f53cfea354fd7507eea357cfec7604d9a2ec4ee4e8431f9e47e8c1154492a07ca51fcdd0e1b4fbbc791fe8700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000220cbaa9de5519fddf3f95f375878f20a7b590612291421384f0b3fcb7e03ff19e43c12e2e1f23457490d835c3fafca8267d8feaed7507273d02c60c827242ed951fcdda21b4fbbc722820c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b854d80d03c51cfab1deac8e9d44713a7a1f1fe4d980c7cd693f92d8825d5912289020542fc19d6256177b26cd73edfaa343034ecc012cf6d7c6dc832246738051fcde851b4fbbc7988b5a55000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023d00ccaaec9c04b3982e6f56e03c17d333cf93ef2d01365d689aa5bc86e8af5796ff927c89eec2f4bdb5d26188455870b9fd72aa84a6ef7fc5f4bb02f4337ceb51fcdf5a1b4fbbc7a68fae6a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024c7379d2b291ad3f0489aa8a8f5f3a4367344a651fb9e0947f07b5fbcaeedf3de78c1c9f27903f3cfe8754785b9f4c5efb8ad5401d95a1aa93eb9c1743ed876751fce0561b4fbbc728382d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015ea10961e32b91fed7a09d8df4c5be71e26df1f7bf236dbbd8f214fa28bab3211f2f4210307a056148bc073df5cc1f16ce2bbdb790ace6647f708c96db6c307851fce0a01b4fbbc754617300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000245490633ce907747fa202b303983238b550dfdcffc0ac06da5edc27c6eae06b6aafb93e2dbc0fa382584e5e40bd5fbfab274a5887a3bda110dd6a667d51aee5351fce0e71b4fbbc765501300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001aecd70a064149ff607f6821017543d1d828266f05a7cbab31179e6aee7fa4b5f071cd770a87baf2780a998d977e440093dff54cd31030fb9afcb6669894efc0a51fce1a81b4fbbc7f1228d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e3a8a7bf19b93e6692c562888562db409a4f7b757c057310195f9fe4e9380650fd72f221cc544608a10b7a7a1abf331f0928d09db1bbb5cc7e090aea167d155a51fce21a1b4fbbc7066a0002000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028796bc88733e089d093ceea8866e814c65d2d63efa1e38c2059eaf8310f189fe5c63ca096f17775539586be874fb753718d293050987f075165937c2f867a3dd51fce2b91b4fbbc7c36f3a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025e085976cf64bc49f1a2b11c5277a7e93844b38c719638f4ec2ac48c37b9f39f153e61622efd965406496f745476306d3d128aa6902d3d9a8bafd636ba562d8c51fce2cc1b4fbbc7e2fe1c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028e261cbe4342feab6a10fd635cae1a0640fdaa1c1744b6c9ad8ff31efb896794d86a3306f51022a59317baa276dc9305e68314e059d9c572a294e689cbb219e951fce35e1b4fbbc7adff7700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f4cedc4af376e3a50448a93633a9a34e332360f8cb25d2b834e9ff8d83baf6b9b67a25457f930974a78c33c5a6bce11e361d37c4fa1f95759fddf2deecc2e27b51fce5411b4fbbc7d797bd00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c437d26ceb1c186bee55e444c28192079015d0927d65f359b78d4d3b6e4a733230def4dadecec0a9cd38f775bfa33bcf0124f2a10b4a4bf44a0aa65d1cc72fae51fce6161b4fbbc760f0c700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fec2f7430d1f8d5fe137dd05ef0d7477d33fa3d469dcadb5cb6774dda1b2088562bcacad0fa35110db9805e538c5bdb1779d80755f1e9399f2185cce7e10868e51fce6b61b4fbbc779954b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027d782f3a4c5f3e686fc774d18a68a65a654b6b229eef50c4daf3ad177d1534763b359b1b3396bec3fcb5a67cfbf44ef35f556bbde8b8aeebd1f631f446c8dea451fce69c1b4fbbc72525d600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a383f8e5eb16e38098df3103fd5671d2e6bb11c9081321ba7fe38ba970423656d34645b174c9f61e369996e3257c56e9dcd3698aa54d3ec29b5364b4b912421f51fce6b21b4fbbc71e026f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ae1e954c72751f6b3e5f5d477b67c95560d5bd8a42ca14b0115200038f8983a8652a418b517f1390f7f2d7f25942af430bdffb8252ce85216ffb6b60fb98b2b051fce8c81b4fbbc7902f2600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000160448b42c8dcb9af9d7e72316b53ed971a24b1bff2b886f03faada5ca19efb46c77b3be231de3d079e07e3124286bb7f21821590f6b5d6615d0b3b477121341551fce91d1b4fbbc76e721f02000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020990832fefa28f4bbe717dd19eba4586a542d91c3393170efd7a49fc69fd20ecc80a87c9ad745ead7d60e6d3bb525093da44acaa824014d022151cd71dd95fd151fce9091b4fbbc7c5ae1400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c6f58e8bbb60025a30bc248601d5e6f61ec75750e5529aa9ea3414e0069064e182342b7e2047aa393e91901c4d79fcfdc3547cfeedb380c51c86fbaf5c0f1d3251fce9731b4fbbc7052bb301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021b992362f990b7e3457360023d8fc39b1b64941dfbe1ba4f31c6b941a9aedd2905d03fb4d89ed238d5b02b5d6e119aa3a8c6e83a5b75ce11ab705023693adf1851fce9f71b4fbbc7826c1201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c105f358db8d7139e952a5df76737f2ed66f1da6d9e767dc918cada6b078a12936d0dd2bf7c1985edb4e5738c779c49fcccef1756af882fb9f0d2fe39fab80cf51fcea301b4fbbc7b9f3a301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000160ba0bd4069259a28e031142c4f857a419ea3f557c5f802ab3543d56b8c8fefa6a0f2e5e510a93caabefd77f3a4f429c5fa31d5b58540db676bd79f0c413b94451fcea6c1b4fbbc7b7940b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002cab69981b18eb7af7df41f21c50ec98cb899d4cc9a84613917a3b935ef878f2a39e377b702844177dcbedba54ad05ebb19552d4824a43bddd94a7631aa9bb79d51fcea941b4fbbc7a5e96f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001b85d8b2c9db7c883892e87196d8e766ff9da510980b45778ff79434627fe8e37e113b4b0ee16604e7591908c9639744bea7def1e96e03bfa72a51ba7c42ab54551fceb911b4fbbc77d793600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ef982c3a89695936ceedaca8d59131659c802459836089fbd9f4037fa637085ebf2ab0f6801600f2f4d7aac293e6565625617b516f8c16c216f61ce3e0a2bd0251fcecdb1b4fbbc7f54e4801000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002af989fb7209430ef8e76d95697a998917d06656d311624b2ddf02de62badf40c6d877c6ac14aca492f3fad8ea450f4042c7eaa67af2cf9ec57fa74a58044228651fcee8f1b4fbbc75dfb4300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010f40c59781d2d1a7dd87e4669f0ddd0f369b765906a4848156c5388bd671e3fb79f343c630e22a4d302712e4cd468f0d2fa12614526993af01c2cfd82aa4d0b351fcef211b4fbbc7bfc55c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029692042365651b2a9766d10f149d5cf4be048733c2e41cf804cb7f91144e8e79d3bcab6378da820649e82ec244f55aa0f1561404999376dafc79cdc8d0c8c56e51fcef371b4fbbc76ba83b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029485c95b24742088eddbf90c4ca6978a1837225695cb209fe0413e4d8d83aba3b494cd97e93f98731de017cc13c1de938b921d9069bba12d4eb9d470138846fb51fcef651b4fbbc77b285f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002dddbe3aef050efdb57bde94d00463fd35644a4b88ae26118a2a3390e97d686a5da2074e7f756afe3ed4df84bd2d621ed5286165c9c6155da5523812f6b15a1a051fcefc71b4fbbc74c289d01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d8acd1d385da17c3492c3206371bc6b423f9ebd69bc3577652c6ff971c8531d8c62b2ff16a6f971a7b9789e85167c738804dc8ba0a6ca8bf733153d585ae6c9951fcf0111b4fbbc774a5b001000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c9439f9a0ac4e66409f9dc9c4a60f915daaaf6a0dded0546d267b064d9652be59445294a94094722b1e7e67d0212d2edf40c5f97392509e877857a332f7efad451fcf0561b4fbbc772033600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000163e606c19fc1a2df4528ae6c657333763dd7ec612cb5764a1afded0837a326c03d6fe3255286c9efd99bfac6d6231e692f8ccb8a5d4215a3af8b552dee72c5c051fcf0951b4fbbc7dd2b3300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000204ceda0646094d9efd966a3e459f86ef289bdf331296394b608d0b27126c532da6c598b3ed624dd8e030a5872ea46920ca3b8486f836c92d19b45a2458c33fc051fcf0cf1b4fbbc700018264000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b5ee5cac3dbb5638677b017c4dd6d174e31ce550600eae3a2e86d7e149ba0bb16cd4ee197ce6002a5638236ae60649d699e6b126762f3209525b908ed0c115cc51fcf10d1b4fbbc7febd0700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f361213b42c4ce7074d83d257f00786351b410b9d80fc8f04ddd7cd1a04bb7075c655cf598228665c10238698dec09c7524bbd5c1c8f143407403d3f64f7697a51fcf12f1b4fbbc74f65d300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029cc74861da6f5d173a8418d890aff73321a6ac12c37aad06d64edc0ebb63a66d3b6a73047701a70f8b2752c714e93057763ef3ec021fec180cbfb5f654c1789851fcf2371b4fbbc710c2b300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001cd2ed9b69e9c7353fa9358d6e56c06299e33961e1da67423890973142762a713d42599be81961d694e820161e8e857682b5e94214b03bdebfabc3b6e523ff6a751fcf30b1b4fbbc7e7f72300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021464776a25515b9d63168f2416aeed49260d8c83478a86a60d3a4095d178846659aa0b0027c41fa5a4640115738518c4d238f58aa2fc7f6a45e7e02ba704f37f51fcf35e1b4fbbc7312d5800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a8b9d636ac7bcce5e70432288bdc904f4be99e4aaa8707c90950b8dc6181740388e176bd2ac1697781410d25b9b702605f1f99a5b7b87f7354f6d83f959ddf8a51fcf4b41b4fbbc7cca41500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025efbd894b0895d89da1d5f924abba507c01e45bf1419795bac8cd6f1a377d3a946025ecb4e1e6e26c970c019151ab22f45193cf8b566313fc9b2d19fd22ea82b51fcf5f41b4fbbc739a02900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024aaecb4c2b2baee08ea98e3e4a96f4a3e3c8d624b5506565951177cebd5001920b2950427e14dab0163d4541dabd270544a86ea2452414a5739861c62028ec9c51fcf62d1b4fbbc731b62300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000010bcfd22818fb8e6d14c99d04e9cfc64d105223e3616e30776ae3cf5e6218e6919d48c638501df84c157c953f8ee2336bd22106d485fd288caacc7a371224115051fcf6ac1b4fbbc76eb50240000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024965f2f37742cf97636f9c34f71db02f865ea30485e3c3120432d8ac454b8fb9fff54822975cf6dede0a23b60f3643e17cfa06e1611278ffa5fb008b221fb05a51fcf78c1b4fbbc73e2e4101000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000244f6057d514b7479f4a1ff68c8ca0c1be7d4c3ba162b9a0648dcf10a44e267a74fb401ab69b64c2509cddd11e8a95c4032a4e9e75f0d9c7479b9a9a0167f885f51fcfa391b4fbbc7ed3e0200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b0477acfa875a10fbfdd295168b6b2fc5cbaac3e157506f41dd036d3f48f7758918eec891e965923e1cdb197fd3e5a7396354b9ec2f5b97b5aaad1df6a76300751fcfaa71b4fbbc7b4a4c300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000244326e971eead375d47afab0660de1f5fa14ab9311bd32cf9d159cbb09cf20057a6b489b4b6f9d5dd1fb4466d6eaa03be95d6f159b15fce61ea81844c2a28fae51fcfb1a1b4fbbc729c02f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022a1e117e5f062d434a9f102293cd3469abf9b7f31abd2f1fbc27483c87e6f773b97da4751a197264fe1c81d888fab6157701f70a1a40ee2ce4a78cf7becf150f51fcfb921b4fbbc779090400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017c01399dc93fcf207b0dc507908c716683795594d48aa2569e0281c2acaddc70930efa0057946561e1e978d4af38c12ec8baefceb3fed42b98c334a68b13e92451fcfba01b4fbbc723513500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000121e7020426b967c4156bad65cb13299f0b1f22fb91dc5fd1080b1d76f31590f764e39ee190b627f92a22356898a3be65cabd3d3ce50b846d3c5a4a326b90476351fcfbcf1b4fbbc744505800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029baacb937a16751a78e1e3b2735d8b4f6a17d10d0cfa4aebc893b3571313b58663a5219b140294e40625ef36d6e9993697be54bf2553a4768ec2b7fc45bae25b51fcfbde1b4fbbc700009f94000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021ce47055a543052cd77903834fbc095611a40bc7eba3f8b7d1d4f588528086b0a64d3e24bc5cb38bf34943db050acdb08d3d84fb66425d7408d26053767dde6051fcfc881b4fbbc7b7fa1800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c7a3bc9244060895c7596f1bf34c358392625f5bd9c9e9e6d7287d05ae28ead19da88e3f1860768d5a424ecdf8f7844469afe2738f68e85f7c3e3c59fe01d4c351fcfd461b4fbbc7aa2100c0000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f085e201804eabb1f97ed34777d56001587cb82bbf5d6e4e1ef51cebe758b676c391d7934c9161cd5643d5e1ee38636c8f696cd7be8a32685207e7cd6951478f51fcfdfc1b4fbbc7b8718c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002de424cc6a853b71f9196a3ff81d4fa7c2dd121873c5c63b10134af2a7369a9220cb7f7b9db1cb1fff667b54f7c8059584c9d796b80388e72c6ee5a8e781733d651fcff231b4fbbc79d413200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000294a48c67f81132c7d46c99f5f552816565cb2500f1d5d14dd9e00c59443d5153f952a9702a072ea5898cb07a1fcdf54a7f2156f25bdfa2b70c9a79cba4ea9fa451fd000d1b4fbbc71dd01400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023889ca2de2593c20977d88405ddb00a3f5936d3eebaaeb3ed54a85b231363f0697a3ac667f0bebfefab50f66dc81daef9dbbf1fd413eeb8499b0ed2f9630301e51fd00bc1b4fbbc7fe353001000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023e2ad1b976d6467c9eb4ab146ad3504cc0c229ceccabb4c067ed9154b1d2fa2497fa3b2044c9c1e8380841ecff9870511b67c7c618a4325e63b0a308a668da7551fd01c21b4fbbc72b987700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e0fc1cae16a5062bf55527d90c01a7859a7dc271edce2468551ad2806dc08f409653ebb7637d6a78d4eeb75edd126ef67d4e22ac9d678519b3326018e5b8774251fd02551b4fbbc7fb591900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001abd057869b5b4bba7dd1340852f97cb2af6b998bd636b5fd1f5a0a3c4c816aedfe7a8f63ef9cc041ab42002258fa9d5a6d4bfede545737403009c64b7835f02c51fd02fb1b4fbbc7e3871f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001853c3586160207cba66dfcbdacd5f671250d58296ca733f82fda70140bd302140bed5dba3ff147582d61a4ac6d34b48c92782ef39e9600ef099c18b4271e86d251fd03041b4fbbc7034de800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027b17679c8be5c9ff163104a37a4f94374ec637ea8387cd02eeeddc6abde87c7524fb690497368a832fcb58c8ef117b56682f3f88beda4ab51e089a959602f6db51fd03891b4fbbc727d63f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000242c88aa02db62f9ca3840762af9184762d3e1187de280f10925b61c48c63163b5157f58cfa53b554456046974adb1af3d2afbae1335accee7d085b8abf20d8ee51fd03f91b4fbbc729f9ad6a000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000273df8733bc7dba509addfd7546ec3202f8c815a022127e03502bc4844108ad5256d663c59713cba56c3fe71ab55c60799f6c62e70cdacb7d09bd9b567ec5734351fd04a41b4fbbc7ad210b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029c2d2689354d1712c9a7625565f8cd6241a3a29213e49e116d5e0d0c6eb317b4cebe3f6e50396f0e4942c4a698393051114d7cef31188f9089590488e5134cf751fd04da1b4fbbc7d2303b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000200336241733ee14e30b95cb8222d7548a88d4144a6592e171bd5816c388a89cd4449d4bba85af4ca7cee9aed7bc02c72cdbd8dd706506ae4efdfe31e4806a6cb51fd056a1b4fbbc73f194e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ae6d01d9d435a89552bffdf18a104b5a6a1f338a4d831ac3bb1b85bd07cb71661c5f09302ddd01c7d33d30fe173f8af202acee5d94ba03443cc8890fdc1bd66051fd06211b4fbbc7ae04ae00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ba39d9a1d54c9f8f06c8cc682ff1c80730c052c3738161449cbacac15efa08626b512b6d27157398920076f554b169fda1f16a2ec961c7ac7c7e3af932bded1d51fd06571b4fbbc76c6dbc00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000217dcb433f2e6cc657e3a4e3b859454ffd0bae2119ebebbd2852dbe3ed5e14e028f7a06f3d317f8cc040ea8f2b7beb2aa023f2cb438d43c3f265d917ff7516b4551fd087c1b4fbbc70b2f0400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002faa36d901e998da057972d96d091ff0689e8308776bdc5e5d8f4e3744c50841bc165a4bc6fed2b02e84aee0eb7968df6949370a5c4ef9eb6a0bccdcddc2ae68d51fd08ef1b4fbbc738a60f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b55b29a69dd5045f1a50cdef03c68485c3a67f0c0bc55da73035ed66d6697cb04bdade3e48551fc471bf51049480c7da00f45c18ee66591fb83d101de2d82de451fd09631b4fbbc735549301000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000017fddd9e00c22fd46cf533162316290ba5c36d3a76164e59b8c976aac9dc52c9e16cbdff9ab03eabfc65677a8330c74f7aecabc1632bb58224823debf405579d951fd0b801b4fbbc7cc674300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024c8dfc3e8a3da0d665e2b3a7730bb79c93539f1fc9a659cd57e796910321bb67804dfa4232494bc10effcd0a0e6bc8b24750a5918c47f8a7f1d1c8e2ee2bbca451fd0be01b4fbbc7e7860080000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002c2339e102c06df4e0c470eb19e2a30571bfb985bfe96e838758c40f05d055a1be02cd1969befa1343191523b6df67bda060dfb681a596e230e27b73c12402a9851fd0c021b4fbbc700013852000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000260372583b75ea6070f8206e22dd6cf6544056f64bb4716dc5436af0e30e9a77a2109818dcce42bacf8b761c5cfb721dcae27f16ed50b785227d01206667f44a351fd0e151b4fbbc73a036000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f9649255031be04ecb2476ab00b1279370aeb1aa8314072a52b90f83fa0a55e73b6dc7dae0cb2cb030c1436752acba036f7ac8549efd2b406993da8f9c90435f51fd0de31b4fbbc780a89100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026d7de70fb5cebbb393a2bd1601699821971dfc3ef9b07a43206bd86ca444f5b21a7989bee6fed977567b4cb650ac8d953cfef2a9a1f1e4bb7fcfb6466a0c3a2f51fd0e541b4fbbc7eb291e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020c27eef7a86344b34f08ef01f0571037434f94b90abf323ef860d969119892f81693037c7fc3f1723e26a64e155979880ad900bf65224cbf8bd31781de1d6fd251fd0f081b4fbbc7bd510500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013bb7d1e93e93a06b8c03a3b764f493e9e282fa817f61f2acf09c21942f5bb4f46e9639a47b74c3ecb2afc710f35ea354338d3c1005ef3d8eb3e837bb2c68e81851fd0f3e1b4fbbc7fd898400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024d227d029da2f41cfb75aab667eeacd421f809aa742e5ba8d142967b2bfbd6f8a9a0ef965e563947590d224dc1e46d9db65cd5b078e03909d48b9d627be6bf6751fd0fca1b4fbbc76d7f3200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000267ec9ab255491c0e58942d9ab1bf3f27bb0437564903f01f5e912e3cae2b82b0cf4fbc2d4d82e63c6c02c631e14862ec2842188d0ecde00f96ac7f7af89e88ab51fd0fe91b4fbbc720c02300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000140f8187dc5e433840c7192e215ef1d13b11e9d5abac32b3984b723907f7e44ddba2fd0a416018eba3a5888263465bfb0d05fbf5b138b6833a41bd28a06395c7651fd10021b4fbbc712900600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000181c2ee93319ef918c96fc8fd6207ad3dfaf3e9e42c8df44f2825d020dc962235f2ab2167df6b63883f8c1f4a4835390f36751c6de414ce7bd67b5d8bc12d1d8f51fd10bf1b4fbbc7cd6e3f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000271b98f9d560ea692eb52b8ef21c1228ebad2d1d6647c1eec4426dc41c2e1f6b0e4898a904381f0eb6d819cb33d819c92d5ee9cf8998b255ac2c64bd58128ab4e51fd124e1b4fbbc7b4b07a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000217b61ee994ac59f8a5c5b15d734b992a95ad9add4725f22bfdc5d00dce70339c5b87def0ca7c261294ff875f1b6d91f89d7e65d12e0e29a6a31871dafb9cf45951fd12b41b4fbbc70d8a1400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e19a5f11edd0ee9b03f6549524e1817581424fd26c4c4a5aba96617c2cef4ade3b1ab9b82e7c0beb98af67df465a54709d07be91ec604b9e089bdc91fcf257fa51fd13e31b4fbbc77d3b6400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029c89e0cc07ad308a2cc6242fc36a91c07b59b53cfff23314212c9bd4c3f1f9c497fec7f5577c8c7e5afd4f6d1ae239752373c94a9fb8ba5cac1c3f46758c694e51fd143a1b4fbbc746c603e0000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016faf3137f9a1e7b8f85449ddcaa374eb08b1ed88e82956efdd36606fed26aae91bc3d314990d383d3072430cc96a4c0a49075d2c8f92183cd44841a49ef48de151fd14da1b4fbbc7d365c700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002116264d51be8c93190cdc463b0f53ee1ce8c5ace9067d3d1715356f4653d17ec273b7de14dc40503c8b2654af166f48b5dab8f71171ee2a3ac9fd4bea3b7d02551fd159e1b4fbbc70db36b01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002409883aa6011e4ab55f703f8d333abe314157a89d836f7e5081e6b0752c2ab514e10655b3283145b4781fb03445315be96b55cfa9869cdf4a18ea27f2649fae951fd16761b4fbbc7df03d600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000211ac2365d1e8b884e918962b76edf23b5f88ecb0dfd4cd0f63e2daf319e2b2cd3179bf19f5119cabbbd8ddb0f51935a3646d77182d79b039d45edfd5ada78e5051fd17401b4fbbc70b125002000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001db0408c35637e7a077f3829f50b63221eb678504b7e44d9ea5d076063abf3db971a0f23281e0c529e66a297b153be6a4182d281bb01f956733402a2a8b7bdd2d51fd18461b4fbbc7c32f0080000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bb56b35d940230ac199222b17f7c1a303f195526948e80226b40692eca0483b389241d020a109f02bfeb1592d6b7b9556c5624443107f61db3acf076de95838c51fd18001b4fbbc754aa4900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002018883f25cf56a41fcfb4162ccde1b7bf8c221d6d55490ee7cf27af81e41d6b79d037c61b6b9cea3784e1b594761afe4011f677a4327845d41b0acee97d0494e51fd18771b4fbbc7f0710a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000197cd87e16b628c1cb9be87579d6f263cfd8b9074d97eb3b6e3afc6fe9fe62366b11de9b8a475cfeb13d3cf602a516fb52ae2a39f7747b26833f84ae3a1931c3a51fd19e21b4fbbc7c6775a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000014e9d390a34d1032b7e54017f184ccf1a80c9c4df6b413b2f2dba51233d2361a49329177c86ed0e91a9fdac07ffcdd077c4e500b20ab5b260fb5577e2b4022b9051fd19f31b4fbbc7c6f25b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023bc408e0b7e258057b53d0c813704e1a6c80a7ab2042513b494c14671453177f9741d748162efa0a65d16d3e6c237bb990820e0228a11de7982cd3595053109851fd1c491b4fbbc76f993a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000236b3b1062b17fb134f6c6bf37d6b9a63c45c0fb258755a3d1bbd56983bff3a01cd3662ca19d9af695570126492d468b1dc130f896fa43238bfc216f96a869ba451fd1c701b4fbbc7afbe7a01000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000217a552201b87d8f77f50b53fed6c76daae2ec0b900f2ab6137bdfb0a447d39045e5d475dee8aa89009098dfaac8153f5bbe6f5027a35e178b4581164a2be489b51fd1cbc1b4fbbc745e05200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002ece00491569aea6318cdfb185c3ceb082c7f06f1fa422a66c84cbe9f9f134599334d1c7742e7c89c58d7214ed9b015b5b57da893c883048aef38ed212230449351fd1ce21b4fbbc7449ba000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001e9adabf5110cf2954719fbfd666a32476ce67e35fa5aa1f5cbb84c7f16ef3973c692912a2a98944f5dd271cfd29a27c66743c102b18c33d5ed8dc67f78d9aee051fd1d061b4fbbc717f50080000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028c59ca07863673ecd8e0c5bc777d1e43416d88a10e708a9b9a95c56182e235d81268348b7f5971817a73d19b88a12e13884e0148e50006022a51be77e42766c651fd1d461b4fbbc73a996c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026bea924b58cdd3e73981eeaee57adc5bd327936f6d557c0f565b3ed50bd0e613d42422ae67208cb96f3dd3a7e44627e1dd4722651278da653aa874f8e116e69851fd1d921b4fbbc791a81800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001458f21bbca131888a01b29b3a48fe829479f83d268891cfb0a136fce033ebdaac9e7eb2fb6fdeebb5cd57b99d46f49834b17f33456ce1343d868c8dc138e28ac51fd1e351b4fbbc7c76a0902000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001fec238e6c1c9dbbc915293ea24c27e38bbd86a5e6711f3e91326947304c629e00e6b35360f0dc704c93197acbe3e3bbb54d0d5a3b52c7b8664c5c61a00af471551fd1e7b1b4fbbc780e12400000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001126f86f09559ced2f2b5f55b51394f5b9cb5b7b2edc25d3c466115a49db8a45ced649b52ffcd4dda8af9d9be0e858194e76c80f6e22e999a7e41ed8df1ec508051fd1f741b4fbbc7955b0a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020aa4eaabfbe95af39f8245bf4dc19d7eb400ae48295760be8ca10bb83d0816d37b6014363c3a0598e422db08fe998447dde51a7d1c085edeab3cc5e361a305ef51fd1fd71b4fbbc7ebfce100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000011bd265a241049b8922c28cb534e2a9f3a8e8d7249dd292603f7054e95458688894ee11694b7023ce04273e2e249defcbcd930cd263c73a35293a5513a281b3d151fd1ff91b4fbbc794fd0000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024bd7710ec901be0848e788e845da13cb2eff43731ea5ab7380d8f15b2a2b50eb8dff69c5224a4fdf85a60cfa13222a73f7c1b238a14c3aea9c3c83a1525d71b851fd208e1b4fbbc7e1379e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015d7e611ce95f1dfe2e1e07e036cd0c1c92f92e3f52e4c1807f8bd763c56150f8aab5f8d35e1e6d389b9e8190652a5b6b27d8f59456e7964abce982f8c2bc428351fd21b11b4fbbc78e140800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025e1cbbb1a09df4961b54cc81d9b4c69aa21f88c845791ae83361d6d7657e539a6c7a9cf041bd2d6b58f39c322b4db93ae464649910c9157cc6547fe6b256a7c651fd21d41b4fbbc70a7e0100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fddc0ff3a93c6f9671766aeb8111de4a697c47863dd44933b6208fcf64fb45baecd4852a5e0b091be09af61dd3364d679489395c93da3bba67a735fb8336bfed51fd21bd1b4fbbc72d735535000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001a74d87a95de7bad84e08ec8e1a824cb79895121cb2bd10d17c85ccbe0e5472ea1bb1b05fc1d4e469201f4de367c1d90d3c71ca4be5e4261b2c1152db469dfe3051fd21c41b4fbbc7abefd600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021a928cd7f7848c3c0587e00fb40bae28e7a59b40c293b5e82b360f0839416cf8093bb4ddf28661f17a3e682210d943af77ff98aa08beba567561aa2554447d0251fd23a61b4fbbc776004200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000018c360d55e7491d6e725b8b2f3953aebcadab2f0c02ddc1e491e76cb3829d707e87fa16846d1c461bafcfcbc81855ddfe2a6327e5208a3bc4df93f4365c41e43851fd248e1b4fbbc7aea06b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000137244af670578896e90acab37364f7880bf2ba920da3fdc0992ec1af68d6e32c18c39597415d052df17ad81eb077f029003b50e4a485c43fa9f3595180db86f751fd24db1b4fbbc7af650040000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023a89405454c56ad834eadf7d462b875570e17f76b0f10428dfe2ad345eab79f5e7d598d32ec73ca3408377d1156689dafcb0f6da941cae4ce542206ff564856351fd25b01b4fbbc723e02600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000019ddfa840db181348763be78277f062f09b3d2ed7366ed5e358ee5cecb6c57836bc00df17f91d157df6aca97c9b3fb8f5001b937206f90ac80d933c9ea4263df251fd26421b4fbbc7c31da100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001d122e4a1cafdeba7acbd7598e34dab30bf482003f0584fcbfd9c3cda24258a78f4356b0aef6f6a218e7d680897c2feccae07bdd71ca37113e35f9c9d028ca96b51fd26df1b4fbbc72961d000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000013d894eeccb7d537230d5803f942bcd484c0a2e19250b178d78159229fbd3e81446a00f559bb9505ddfbe59772f4d4584988835f0e270da7afac2fbd3b52a963351fd27f01b4fbbc7f8fd8f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002956bbe3623d10efec09052d114710ee108f1fed509d9469580e1c446c2733e42d44b11c6ec3baf2c8f1c137d1a80038f5f2201766e9e2074f1a3b1fa50d82bf151fd28441b4fbbc759a20320000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000028d14a42999af78269c9fb67eceff0a72861101666cffaa6b5fdbdd53a6914ea1cb1aa821de44d1b886478b253ee7fe49a194c6e1aa967fb04c1559bbe33920c351fd2a1d1b4fbbc7208e6000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000204ac1e60b2c90abe340c38d2d66d803f572ed039be975daa4d6d2ec7987ccb76be1388760d94885dce1c086ee61bdc6d55e1ce5d203727ba3ac431be1843c6cf51fd2a0a1b4fbbc76fb00a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025a274c34395d04603a578d6877755a16e02859867bda0b274e8d448f2bca3435109f84042fa1363ea447830fb3d1d1c6888f6486ef87fc8a414f7fdb49a45a8151fd2ab41b4fbbc7b42c1000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000016fa958a6a943d93507bbbe3e1eaf72fdf64ba7a23af4b2faf90c1dd7aa7ef8b70b694f31305752aee0bf65f462004e6f0d58035e7151735499dad5e2bf6a943b51fd2b1b1b4fbbc74d8db401000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002743019f8340718a6844ceb1fe58e4e93ef89457cc10bb76b67b6c21452f3a431fc2344facfb21a2574b1aad1ec1f88cfc04543e4d02d5a571d8790a4a203026651fd2bb71b4fbbc7341b5835000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002441f3bedcf78ecfb5027c3552970d7e4dd79dec9651492f71f5e3fed1628d7b67550a28f5e7efea2e62ad5bef29b8d0eadd257904e0203c94adc29afdb7a8df151fd2b8b1b4fbbc76e6c8000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000022f55f0da8df5f19970f740a650c8c87c2ee569d7136ca47f2bc5e8691b048582e14b9f7e423f259afbec147c90714da6b3e007c2d57554aaaa2339fcdd6edf8151fd2c7e1b4fbbc7fef65d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002e61d32448e4f86f64071db8c08c6b5203c0068c68fbcb01a6ccfbc733dd553ee08f86042e32c3b72bb574bf11748b4e482cd1cb4568f554f43ba5327f5d3e20151fd2cde1b4fbbc799b6cf00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002939c28ba9ffcd86ff63797f6bfaa908964d1657e2b3986ee1a81fb76cfc97f847c31fd67cc6676d1384b50949c32e0f4f2b5b0fe7fadb04ff2fb20d68a951e9a51fd2d3c1b4fbbc754bb8f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000023d9e73023d9ee76ab17cda5aa73c45f75dfd30f918d0feeb210f90d35eff81477d6cc5af108bcf9931b02683c90d5847e2b2a6c7497700c16c2d43030e60068551fd2dcd1b4fbbc7294c7900000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025edde1e86cfd814667a03b75f2ccd32fe72ba2e79f73418fe10e08170188bf328895e8707a7b730aa95676613a55d71630e111963e814f6c2f51ebabde8a820d51fd2eb91b4fbbc702872f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000025f0d9f58855db59788e019c8179f62715e9d5446aa211ed7f9715604b7a976f6794a7260468580927c7a2ba6d6d63e817fe71d6d4b1ec8d27d69cea7cd4430e051fd301e1b4fbbc73c5d5b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002fb353a87ac585a1f9161b78059b4bbb0989735f60621326bade3bf6482ff9afdc5b81cb22e0b22d425a5d3ef2c3f8a7caf635942a749d92b3644885b0b170d0f51fd32871b4fbbc7b34e9700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002d7fa3a7bddf4ac6e378a8669d55a9138f4757fabcd1c6a84a79ae1b21c98d80ca91c7a5c3147c62b314692c5464e55050d2db1eb285bd39914ca33abec11b2aa51fd329a1b4fbbc77a710300000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001ae4e4184892d6d16b3270e2ad2028583883fb295d17ad5534f414158a6b89dc656b27448557aae10d358152458a715888d3e9ce11de49811d0c9f022bd48dc5851fd333d1b4fbbc7329b3500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029d936ed5c07d5cdf5bc332ba6dc7f81ece7b64c432c10b4d063e1b5695b98fc133877048e4d53c8f03d7f88972804852f79c9b6af0c60f29f77ace09194a8d3851fd33561b4fbbc78c674200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000259e8ee90e20ec8f3a767280eb68f5afed6271c88f53e026a51625668f99df75e1ff37976f16fbcc49801c1600399b2995d4fdad97f9cd7e3567c49fd94efc66a51fd33461b4fbbc7ea039e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000026ee3b919481115207ded88775b0e9b70ca6a1b800088888fde675c924de8c912b8b6c6d4390fad70aebf44dea5f22b6937cdc4c05f667ab3db1c60c09d7a184451fd33fe1b4fbbc761447000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000274c0c8e0bcdcaa46f519ac145281e3757ff1d2e66241406f6395c3f75f5bf14b7a614eba38b1e41ca5a1374943c54e662c8c335dc89098fd9df34ffc10838e3051fd35221b4fbbc79db02800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021174797754b1458e113eb7c8be6e6dff7581d0b6d8ff967ec053f669148c2b5878a4b9705ad49c8af877fdc4602d995acac2743f99f6417bd69ba09b3519653551fd35171b4fbbc74f788b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000237cf9a81d615d1bc44d5d7df1f433de4db6ea479889f338fc53a6a87530fc2a1f9dad417ab0cd43473390f9857806c3eddc6b14fee14b94fdfb6c3cc49b47d6151fd36241b4fbbc78183e200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f2eaf948c75ce68a238163bc4d2dfab9b5f95a42d0b5c365808d7ce4e6b0f751c57bb72182c6099c4452289762801af6560f331a1d3a46ebaa267d7c45b790d051fd36d31b4fbbc75b889f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001643dd303a8eceee51ef40425c956a6a23d486f5e62d9eae92e120fcb52207de18a19d27d96d623b74f1631ccba2003719c5d48b03a46bb1c1da88efd483e91d851fd376a1b4fbbc74fbe8201000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001f28e18b899cb9e92402703848cc11ad9b6b4676d59fc277e453cf9f6db446459fabd33d3db05863a5bc749a94e81cf9aca20b1eedf29506316cde03c17b2b6d751fd38ed1b4fbbc7a1ea5755000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021dbed9be418b405ebc82a7d2b75accd0700d7d03ec2a3a7872360add6c4c61e0810599f92ba6dbc13d643b40c9d56eb1a767bc9314f5e45df6e77285e40071a151fd39231b4fbbc7d8761000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001dceb5678d259ad505964c3f618ff5fdbad40fa4d9463d639faeb3f96824cdf8f4fef1500ce26558bca89c20442a278500a8fe1b751eeb2cc9558f53f980a9ae951fd39311b4fbbc76de82d00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000029ddd79a17e2c5f96efb3948587c213bacfd32b3ebd5deff1314dc2ef23cc6ac6c5caf257c2c2aed78431d6116e143ccbb6fcc6cfa0200a7d7157742227b15b5e51fd3a591b4fbbc7c09ffe00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bd6024a93e52ba41f8b665f8713092c0ff389e359203c7cca4f9776afc0ac948e10c3bf5d9bae36c8102e2292cb3336226e414bb734d08bb33194f3a243f15d351fd3b0b1b4fbbc712c90200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000021e6b63a4504be95dbba45b1c88a44533d5a511e81ea5f3ab814908698d038767d63d35aa3792f38f3af709b4fc570889cefc16d54c70345c1f94a8105db8cccc51fd3bbd1b4fbbc7403e0e00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bbc9cd4892123bac28a139f01e91a977036a23f55213ec605a360fb80474ef23ab1971c56f1a3b84ccddb7913cb3590321cceb07705819474bf5a3139fe60cf751fd3d431b4fbbc7f002b000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f7fa4c7fc3eb47d168c7ab47799c6bd47298c15d03466bff7fbdbcb0e336acb6227ed0cd53863856eb8cd0fe4dafd49f84b719523378e38a7039e8e72d8bb3cc51fd3de61b4fbbc7950d04c0000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002a06c2f480fe012315bdba59b91ad3581b5f27d89dcee2d9e7ec55c1167e6c83b27152788770e28828e98892d8b59b71b8af9bbc4486452826cb75ee68eb206c651fd3e111b4fbbc7cd61a000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000020005cb87b09b211f8472a2b2f081a0b3f2d3981bd1b3f97fe835445b4d83986044dc2c2e10f3a53c55b34230945932c86cecd612e380c58ece7330458c3759e051fd3ed51b4fbbc71ffac100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001922524b103ec182c20dddb7d716c250ce131ef21a16182eb6f44c8ce20d00678c522e5b9317fd34bf556deda70db3567ea6f2d791946af9ab26a7ca5c016da8251fd3ef51b4fbbc749908f00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000012e103eafbad0be5057607166f4f3ad80a386f1a9939dabe6d45769665a3ada8d6ab7135df6ef440121a240b616e5edf73e4b4450dae040bbe666c43d0cbe424551fd3f061b4fbbc77aae0b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000015803b5ee3d21c3e11d3d59b03376e0ad2553b0f7a35f232dad3cdbd94ef6a75db405cccd25cf9d16be29f7a50788055a1e0f7cb545adf2354148241495b0cba151fd3f4a1b4fbbc7f2071500000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002bcf6e1e72944ede70f16b4bf0065318f478febf1804f7db33813fc0156eb27b4a46cb86d55c6ddf8be750deeed9f545af4707e0871b912377bf9eccbabdd337c51fd3f4b1b4fbbc7e1102001000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000262461a5f6b1e0d0e32f729e4cfea0f588252b31bc29fc7eeb9dcad4a885b67a18e0f3945b422371e6919b18093584115efc4c932198fd8f67089f98f39768fa851fd40511b4fbbc7673f4600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002741acfcd9a89847915fc74b99afe33158df1f024623504ed11be48624624e65fe913a9e6647fa997b5908ebdd8e4b7d2dd061dbfa4005ebdf566c3f75203cbc251fd41a71b4fbbc7951fa700000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000024ed233c01956b5dbdb9bf997e96c25e37ed1ed87d01de1f44743ba60ddced3c17728473a0d2315a68c1c43aa6bc39a757b5f22f43ede1ee1e2e909497251633c51fd41791b4fbbc726112c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002b08cfe43bae2298866422368bd9682c154eefa2c30e642dfe1becadc7eca915995a4c426ce2693d9a0f0c3266214bed28d7cdad6af4880f7ed9f9fcc9ab7be6c51fd41ec1b4fbbc7ad310a00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000125a92e123ba44c96276713af926d8a73fad5d87499a9e82e508b199a6c3a98b6a2e746de94e7469316033b1522f2c65b362d5459cc7cb770d4d5469be58153c551fd42921b4fbbc7cf026c00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n0000000289c0c1f20dfe2b52142695d1d40f63496d27b6a6c4b3f78fb86ae066a1905e1f4a0ab5178e80fc7f96215a43767d22f8d8603da5dad9a6d8ffa5a35cc58b01a951fd42581b4fbbc7d7e26800000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000001c6adca1a23b12d62292654e82b2904cd6cfe7bd6accfeaf5329567116ed879f61e2e6ea1f66231b5fd6d72231380f23a183fc7040a185280b8153e1a266115f751fd42d21b4fbbc773487200000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n00000002f1689ffa74453f36902fa3b72c93fdbaf927f3dfa42e0b9e4795c827da14aa3773f884ceb62ddedf78d938de6a30d049ebbaae9919d86f8c9b3368e9032e345c51fd43181b4fbbc7e4d56b00000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n000000027fc171c138828792b1fe994e3d3f3d51892538ebaa5395f7c976b1f13a870fd91c7e773b88f40716b16a2454bed27e7dd6d4a5611e1d2583a60c5a02f0b4356651fd43881b4fbbc7e4dd5600000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000\n"
  },
  {
    "path": "scripts/utils.tcl",
    "content": "# Reverse a hex string\nproc reverseHex {hexstring} {\n\tset result \"\"\n\t\n\tfor {set x 0} {$x < [string length $hexstring]} {incr x} {\n\t\tset piece [string range $hexstring $x [expr {$x+1}]]\n\t\tset result \"${piece}${result}\"\n\t\n\t\t[incr x]\n\t}\n\t\n\treturn $result\n}\n\n"
  },
  {
    "path": "source/altera_pll.v",
    "content": "module main_pll # (parameter SPEED_MHZ = 25) (inclk0, c0);\n\n\tinput\t  inclk0;\n\toutput\t  c0;\n\n\twire [4:0] sub_wire0;\n\twire [0:0] sub_wire4 = 1'h0;\n\twire [0:0] sub_wire1 = sub_wire0[0:0];\n\twire  c0 = sub_wire1;\n\twire  sub_wire2 = inclk0;\n\twire [1:0] sub_wire3 = {sub_wire4, sub_wire2};\n\n\taltpll\taltpll_component (\n\t\t\t\t.inclk (sub_wire3),\n\t\t\t\t.clk (sub_wire0),\n\t\t\t\t.activeclock (),\n\t\t\t\t.areset (1'b0),\n\t\t\t\t.clkbad (),\n\t\t\t\t.clkena ({6{1'b1}}),\n\t\t\t\t.clkloss (),\n\t\t\t\t.clkswitch (1'b0),\n\t\t\t\t.configupdate (1'b0),\n\t\t\t\t.enable0 (),\n\t\t\t\t.enable1 (),\n\t\t\t\t.extclk (),\n\t\t\t\t.extclkena ({4{1'b1}}),\n\t\t\t\t.fbin (1'b1),\n\t\t\t\t.fbmimicbidir (),\n\t\t\t\t.fbout (),\n\t\t\t\t// synopsys translate_off\n\t\t\t\t.fref (),\n\t\t\t\t.icdrclk (),\n\t\t\t\t// synopsys translate_on\n\t\t\t\t.locked (),\n\t\t\t\t.pfdena (1'b1),\n\t\t\t\t.phasecounterselect ({4{1'b1}}),\n\t\t\t\t.phasedone (),\n\t\t\t\t.phasestep (1'b1),\n\t\t\t\t.phaseupdown (1'b1),\n\t\t\t\t.pllena (1'b1),\n\t\t\t\t.scanaclr (1'b0),\n\t\t\t\t.scanclk (1'b0),\n\t\t\t\t.scanclkena (1'b1),\n\t\t\t\t.scandata (1'b0),\n\t\t\t\t.scandataout (),\n\t\t\t\t.scandone (),\n\t\t\t\t.scanread (1'b0),\n\t\t\t\t.scanwrite (1'b0),\n\t\t\t\t.sclkout0 (),\n\t\t\t\t.sclkout1 (),\n\t\t\t\t.vcooverrange (),\n\t\t\t\t.vcounderrange ());\n\tdefparam\n\t\taltpll_component.bandwidth_type = \"AUTO\",\n\t\taltpll_component.clk0_divide_by = 50,\n\t\taltpll_component.clk0_duty_cycle = 50,\n\t\taltpll_component.clk0_multiply_by = SPEED_MHZ,\n\t\taltpll_component.clk0_phase_shift = \"0\",\n\t\taltpll_component.compensate_clock = \"CLK0\",\n\t\taltpll_component.inclk0_input_frequency = 20000,\n\t\taltpll_component.intended_device_family = \"Cyclone III\",\n\t\taltpll_component.lpm_hint = \"CBX_MODULE_PREFIX=main_pll\",\n\t\taltpll_component.lpm_type = \"altpll\",\n\t\taltpll_component.operation_mode = \"NORMAL\",\n\t\taltpll_component.pll_type = \"AUTO\",\n\t\taltpll_component.port_activeclock = \"PORT_UNUSED\",\n\t\taltpll_component.port_areset = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkbad0 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkbad1 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkloss = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkswitch = \"PORT_UNUSED\",\n\t\taltpll_component.port_configupdate = \"PORT_UNUSED\",\n\t\taltpll_component.port_fbin = \"PORT_UNUSED\",\n\t\taltpll_component.port_inclk0 = \"PORT_USED\",\n\t\taltpll_component.port_inclk1 = \"PORT_UNUSED\",\n\t\taltpll_component.port_locked = \"PORT_UNUSED\",\n\t\taltpll_component.port_pfdena = \"PORT_UNUSED\",\n\t\taltpll_component.port_phasecounterselect = \"PORT_UNUSED\",\n\t\taltpll_component.port_phasedone = \"PORT_UNUSED\",\n\t\taltpll_component.port_phasestep = \"PORT_UNUSED\",\n\t\taltpll_component.port_phaseupdown = \"PORT_UNUSED\",\n\t\taltpll_component.port_pllena = \"PORT_UNUSED\",\n\t\taltpll_component.port_scanaclr = \"PORT_UNUSED\",\n\t\taltpll_component.port_scanclk = \"PORT_UNUSED\",\n\t\taltpll_component.port_scanclkena = \"PORT_UNUSED\",\n\t\taltpll_component.port_scandata = \"PORT_UNUSED\",\n\t\taltpll_component.port_scandataout = \"PORT_UNUSED\",\n\t\taltpll_component.port_scandone = \"PORT_UNUSED\",\n\t\taltpll_component.port_scanread = \"PORT_UNUSED\",\n\t\taltpll_component.port_scanwrite = \"PORT_UNUSED\",\n\t\taltpll_component.port_clk0 = \"PORT_USED\",\n\t\taltpll_component.port_clk1 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clk2 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clk3 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clk4 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clk5 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkena0 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkena1 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkena2 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkena3 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkena4 = \"PORT_UNUSED\",\n\t\taltpll_component.port_clkena5 = \"PORT_UNUSED\",\n\t\taltpll_component.port_extclk0 = \"PORT_UNUSED\",\n\t\taltpll_component.port_extclk1 = \"PORT_UNUSED\",\n\t\taltpll_component.port_extclk2 = \"PORT_UNUSED\",\n\t\taltpll_component.port_extclk3 = \"PORT_UNUSED\",\n\t\taltpll_component.width_clock = 5;\n\n\nendmodule\n\n"
  },
  {
    "path": "source/altera_ram.v",
    "content": "// altera_ram.v this now takes parameter ADDRBITS to set size\n// Use ADDRBITS = 10 for 1024 words, 9 for 512 (halfram)\n// NB since I HAVE edited this file (contrary to the warning\n// below, its probably not a good idea to invoke the wizard)\n\n// megafunction wizard: %RAM: 1-PORT%\n// GENERATION: STANDARD\n// VERSION: WM1.0\n// MODULE: altsyncram \n\n// ============================================================\n// File Name: ram.v\n// Megafunction Name(s):\n// \t\t\taltsyncram\n//\n// Simulation Library Files(s):\n// \t\t\taltera_mf\n// ============================================================\n// ************************************************************\n// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!\n//\n// 10.1 Build 153 11/29/2010 SJ Web Edition\n// ************************************************************\n\n\n//Copyright (C) 1991-2010 Altera Corporation\n//Your use of Altera Corporation's design tools, logic functions \n//and other software and tools, and its AMPP partner logic \n//functions, and any output files from any of the foregoing \n//(including device programming or simulation files), and any \n//associated documentation or information are expressly subject \n//to the terms and conditions of the Altera Program License \n//Subscription Agreement, Altera MegaCore Function License \n//Agreement, or other applicable license agreement, including, \n//without limitation, that your use is for the sole purpose of \n//programming logic devices manufactured by Altera and sold by \n//Altera or its authorized distributors.  Please refer to the \n//applicable agreement for further details.\n\n\n// synopsys translate_off\n`timescale 1 ps / 1 ps\n// synopsys translate_on\nmodule ram # ( parameter ADDRBITS=10 ) (\n\taddress,\n\tclock,\n\tdata,\n\twren,\n\tq);\n\n\tinput\t[ADDRBITS-1:0]  address;\n\tinput\t  clock;\n\tinput\t[255:0]  data;\n\tinput\t  wren;\n\toutput\t[255:0]  q;\n`ifndef ALTERA_RESERVED_QIS\n// synopsys translate_off\n`endif\n\ttri1\t  clock;\n`ifndef ALTERA_RESERVED_QIS\n// synopsys translate_on\n`endif\n\n\twire [255:0] sub_wire0;\n\twire [255:0] q = sub_wire0[255:0];\n\n\taltsyncram\taltsyncram_component (\n\t\t\t\t.address_a (address),\n\t\t\t\t.clock0 (clock),\n\t\t\t\t.data_a (data),\n\t\t\t\t.wren_a (wren),\n\t\t\t\t.q_a (sub_wire0),\n\t\t\t\t.aclr0 (1'b0),\n\t\t\t\t.aclr1 (1'b0),\n\t\t\t\t.address_b (1'b1),\n\t\t\t\t.addressstall_a (1'b0),\n\t\t\t\t.addressstall_b (1'b0),\n\t\t\t\t.byteena_a (1'b1),\n\t\t\t\t.byteena_b (1'b1),\n\t\t\t\t.clock1 (1'b1),\n\t\t\t\t.clocken0 (1'b1),\n\t\t\t\t.clocken1 (1'b1),\n\t\t\t\t.clocken2 (1'b1),\n\t\t\t\t.clocken3 (1'b1),\n\t\t\t\t.data_b (1'b1),\n\t\t\t\t.eccstatus (),\n\t\t\t\t.q_b (),\n\t\t\t\t.rden_a (1'b1),\n\t\t\t\t.rden_b (1'b1),\n\t\t\t\t.wren_b (1'b0));\n\tdefparam\n\t\taltsyncram_component.clock_enable_input_a = \"BYPASS\",\n\t\taltsyncram_component.clock_enable_output_a = \"BYPASS\",\n\t\taltsyncram_component.intended_device_family = \"Cyclone IV E\",\n\t\taltsyncram_component.lpm_hint = \"ENABLE_RUNTIME_MOD=NO\",\n\t\taltsyncram_component.lpm_type = \"altsyncram\",\n\t\taltsyncram_component.numwords_a = 2 << (ADDRBITS-1),\n\t\taltsyncram_component.operation_mode = \"SINGLE_PORT\",\n\t\taltsyncram_component.outdata_aclr_a = \"NONE\",\n\t\taltsyncram_component.outdata_reg_a = \"UNREGISTERED\",\n\t\taltsyncram_component.power_up_uninitialized = \"FALSE\",\n\t\taltsyncram_component.read_during_write_mode_port_a = \"OLD_DATA\",\n\t\taltsyncram_component.widthad_a = ADDRBITS,\n\t\taltsyncram_component.width_a = 256,\n\t\taltsyncram_component.width_byteena_a = 1;\n\n\nendmodule\n\n// ============================================================\n// CNX file retrieval info\n// ============================================================\n// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC \"0\"\n// Retrieval info: PRIVATE: AclrAddr NUMERIC \"0\"\n// Retrieval info: PRIVATE: AclrByte NUMERIC \"0\"\n// Retrieval info: PRIVATE: AclrData NUMERIC \"0\"\n// Retrieval info: PRIVATE: AclrOutput NUMERIC \"0\"\n// Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC \"0\"\n// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC \"8\"\n// Retrieval info: PRIVATE: BlankMemory NUMERIC \"1\"\n// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC \"0\"\n// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC \"0\"\n// Retrieval info: PRIVATE: Clken NUMERIC \"0\"\n// Retrieval info: PRIVATE: DataBusSeparated NUMERIC \"1\"\n// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC \"0\"\n// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING \"PORT_A\"\n// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC \"0\"\n// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING \"Cyclone IV E\"\n// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC \"0\"\n// Retrieval info: PRIVATE: JTAG_ID STRING \"NONE\"\n// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC \"0\"\n// Retrieval info: PRIVATE: MIFfilename STRING \"\"\n// Retrieval info: PRIVATE: NUMWORDS_A NUMERIC \"1024\"\n// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC \"0\"\n// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC \"1\"\n// Retrieval info: PRIVATE: RegAddr NUMERIC \"1\"\n// Retrieval info: PRIVATE: RegData NUMERIC \"1\"\n// Retrieval info: PRIVATE: RegOutput NUMERIC \"0\"\n// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING \"0\"\n// Retrieval info: PRIVATE: SingleClock NUMERIC \"1\"\n// Retrieval info: PRIVATE: UseDQRAM NUMERIC \"1\"\n// Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC \"0\"\n// Retrieval info: PRIVATE: WidthAddr NUMERIC \"10\"\n// Retrieval info: PRIVATE: WidthData NUMERIC \"256\"\n// Retrieval info: PRIVATE: rden NUMERIC \"0\"\n// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all\n// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING \"BYPASS\"\n// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING \"BYPASS\"\n// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING \"Cyclone IV E\"\n// Retrieval info: CONSTANT: LPM_HINT STRING \"ENABLE_RUNTIME_MOD=NO\"\n// Retrieval info: CONSTANT: LPM_TYPE STRING \"altsyncram\"\n// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC \"1024\"\n// Retrieval info: CONSTANT: OPERATION_MODE STRING \"SINGLE_PORT\"\n// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING \"NONE\"\n// Retrieval info: CONSTANT: OUTDATA_REG_A STRING \"UNREGISTERED\"\n// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING \"FALSE\"\n// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING \"OLD_DATA\"\n// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC \"10\"\n// Retrieval info: CONSTANT: WIDTH_A NUMERIC \"256\"\n// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC \"1\"\n// Retrieval info: USED_PORT: address 0 0 10 0 INPUT NODEFVAL \"address[9..0]\"\n// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC \"clock\"\n// Retrieval info: USED_PORT: data 0 0 256 0 INPUT NODEFVAL \"data[255..0]\"\n// Retrieval info: USED_PORT: q 0 0 256 0 OUTPUT NODEFVAL \"q[255..0]\"\n// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL \"wren\"\n// Retrieval info: CONNECT: @address_a 0 0 10 0 address 0 0 10 0\n// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0\n// Retrieval info: CONNECT: @data_a 0 0 256 0 data 0 0 256 0\n// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0\n// Retrieval info: CONNECT: q 0 0 256 0 @q_a 0 0 256 0\n// Retrieval info: GEN_FILE: TYPE_NORMAL ram.v TRUE\n// Retrieval info: GEN_FILE: TYPE_NORMAL ram.inc FALSE\n// Retrieval info: GEN_FILE: TYPE_NORMAL ram.cmp FALSE\n// Retrieval info: GEN_FILE: TYPE_NORMAL ram.bsf FALSE\n// Retrieval info: GEN_FILE: TYPE_NORMAL ram_inst.v FALSE\n// Retrieval info: GEN_FILE: TYPE_NORMAL ram_bb.v TRUE\n// Retrieval info: LIB_FILE: altera_mf\n"
  },
  {
    "path": "source/altera_virtual_wire.v",
    "content": "/*\n*\n* Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n*\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n\nmodule virtual_wire (probe, source);\n\t\n\tparameter WIDTH = 1;\n\tparameter PROBE_WIDTH = 1;\n\tparameter INITIAL_VALUE = \" 0\";\n\tparameter INSTANCE_ID = \"NONE\";\n\n\tinput\t[0:PROBE_WIDTH-1]  probe;\n\toutput\t[0:WIDTH-1]  source;\n\n`ifdef SIM\n\tassign source = 0;\n`else\n\taltsource_probe\taltsource_probe_component (\n\t\t\t\t.probe (probe),\n\t\t\t\t.source (source)\n\t\t\t\t// synopsys translate_off\n\t\t\t\t,\n\t\t\t\t.clrn (),\n\t\t\t\t.ena (),\n\t\t\t\t.ir_in (),\n\t\t\t\t.ir_out (),\n\t\t\t\t.jtag_state_cdr (),\n\t\t\t\t.jtag_state_cir (),\n\t\t\t\t.jtag_state_e1dr (),\n\t\t\t\t.jtag_state_sdr (),\n\t\t\t\t.jtag_state_tlr (),\n\t\t\t\t.jtag_state_udr (),\n\t\t\t\t.jtag_state_uir (),\n\t\t\t\t.raw_tck (),\n\t\t\t\t.source_clk (),\n\t\t\t\t.source_ena (),\n\t\t\t\t.tdi (),\n\t\t\t\t.tdo (),\n\t\t\t\t.usr1 ()\n\t\t\t\t// synopsys translate_on\n\t\t\t\t);\n\tdefparam\n\t\taltsource_probe_component.enable_metastability = \"NO\",\n\t\taltsource_probe_component.instance_id = INSTANCE_ID,\n\t\taltsource_probe_component.probe_width = PROBE_WIDTH,\n\t\taltsource_probe_component.sld_auto_instance_index = \"YES\",\n\t\taltsource_probe_component.sld_instance_index = 0,\n\t\taltsource_probe_component.source_initial_value = INITIAL_VALUE,\n\t\taltsource_probe_component.source_width = WIDTH;\n`endif\n\nendmodule\n\n"
  },
  {
    "path": "source/hashcore.v",
    "content": "/* hashcore.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n//`define HALFRAM\t\t// SET this to target DE0-Nano (in quartus assignments/settings/verilog hdl)\n\t\n`timescale 1ns/1ps\n\nmodule hashcore (hash_clk, data1, data2, data3, target, nonce_msb, nonce_out, golden_nonce_out, golden_nonce_match, loadnonce);\n\n\tinput hash_clk;\n\tinput [255:0] data1;\n\tinput [255:0] data2;\n\tinput [127:0] data3;\n\tinput [31:0] target;\n\tinput [3:0] nonce_msb;\t\t// Supports multicore (set MULTICORE below)\n\toutput [31:0] nonce_out;\n\toutput [31:0] golden_nonce_out;\n\toutput golden_nonce_match;\t// Strobe valid one cycle on a match (needed for serial comms)\n\tinput loadnonce;\t\t\t// Strobe loads nonce (used for serial interface)\n\t\n\treg poweron_reset = 1'b1;\n\treg reset = 1'b1;\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tpoweron_reset <= 1'b0;\n\t\treset <= poweron_reset;\t\t\t// Ensures a full clock cycle for reset\n\tend\n\t\n\t`ifndef ICARUS\n\treg [31:0] nonce_prevous_load = 32'hffffffff;\t// See note in salsa mix FSM\n\t`endif\n\n\t`ifndef NOMULTICORE\n\t\treg [27:0] nonce_cnt = 28'd0;\t\t// Multiple cores use different prefix\n\t\twire [31:0] nonce;\n\t\tassign nonce = { nonce_msb, nonce_cnt };\n\t`else\n\t\treg [31:0] nonce = 32'd0;\t\t\t// NB Initially loaded from data3[127:96], see salsa mix FSM\n\t`endif\n\n\tassign nonce_out = nonce;\n\n\treg [31:0] nonce_1 = 32'd0;\t\t// Pipeline nonce since needed for final PBKDF2_SHA256_80_128_32\n\treg [31:0] nonce_2 = 32'd0;\n\treg [31:0] golden_nonce = 32'd0;\n\tassign golden_nonce_out = golden_nonce;\n\treg golden_nonce_match = 1'b0;\n\t\n\treg [255:0] rx_state;\n\treg [511:0] rx_input;\n\twire [255:0] tx_hash;\n\treg [255:0] khash = 256'd0;\t\t// Key hash (NB scrypt.c calls this ihash)\n\treg [255:0] ihash = 256'd0;\t\t// IPAD hash\n\treg [255:0] ohash = 256'd0;\t\t// OPAD hash\n\t`ifdef SIM\n\t\treg [255:0] final_hash = 256'd0;\t// Just for DEBUG, only need top 32 bits in live code.\n\t`endif\n\treg [31:0] blockcnt = 32'd0;\t// Takes values 1..4 for block iteration (NB could hardwire top 29 bits)\n\treg [1023:0] Xbuf = 1024'd0;\n\treg [1023:0] MixOut;\t\t\t// Salsa mixer ouput\n\twire [1023:0] MixOutRewire;\t\t// Need to do endian conversion (see the generate below)\n\treg [5:0] cnt = 6'd0;\n\twire feedback;\n\tassign feedback = (cnt != 6'b0);\n\t\n\t// Using LOOP=64 to simplify timing (needs slightly modified version of original sha256_transform.v)\n\t// since pipelining is inappropriate for ltc (we need to rehash same data several times in succession)\n\tsha256_transform  # (.LOOP(64)) sha256_blk (\n\t\t.clk(hash_clk),\n\t\t.feedback(feedback),\n\t\t.cnt(cnt),\n\t\t.rx_state(rx_state),\n\t\t.rx_input(rx_input),\n\t\t.tx_hash(tx_hash)\n\t);\n\n\t// These flags control the interaction of the SHA256 and SalsaMix FSM's. While OK in simulation\n\t// Altera Quartus II barfs on synthesis, hence the ugly hack.\n\t\n\t// Original version ...\n\t// reg SMixInRdy = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\t// reg SMixOutRdy = 1'b0;\t\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\n\t// Ugly hack...\n\treg SMixInRdy_state = 1'b0;\t\t// SMix input ready flag (set in SHA256, reset in SMIX)\n\treg SMixOutRdy_state = 1'b0;\t// SMix output ready flag (set in SMIX, reset in SHA256)\n\twire SMixInRdy;\n\twire SMixOutRdy;\n\n\treg Set_SMixInRdy = 1'b0;\n\treg Clr_SMixInRdy = 1'b0;\n\treg Set_SMixOutRdy = 1'b0;\n\treg Clr_SMixOutRdy = 1'b0;\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tif (Set_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b1;\n\t\tif (Clr_SMixInRdy)\n\t\t\tSMixInRdy_state <= 1'b0;\t// Clr overrides set\n\t\tif (Set_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b1;\n\t\tif (Clr_SMixOutRdy)\n\t\t\tSMixOutRdy_state <= 1'b0;\t// Clr overrides set\n\tend\n\t\n\t// Achieves identical timing to original version, but probably overkill\n\tassign SMixInRdy = Clr_SMixInRdy ? 1'b0 : Set_SMixInRdy ? 1'b1 : SMixInRdy_state;\n\tassign SMixOutRdy = Clr_SMixOutRdy ? 1'b0 : Set_SMixOutRdy ? 1'b1 : SMixOutRdy_state;\n\t\t\n\t// Controller FSM for PBKDF2_SHA256_80_128 (multiple hashes using the sha256_transform)\n\t// Based on scrypt.c from cgminer (Colin Percival, ArtForz). I don't even pretend to\n\t// understand how it works so please excuse any naive implimentation errors.\n\t\n\t// NB apparently this is poor coding style (sorry, I'm just a newbie here), but its working so\n\t// I'm not going to change it now (perhaps in a future version). It could also do with optimisation\n\t// though its not essential as the SHA256 does not limit the overall throughput.\n\t\n\tparameter\tS_IDLE=0,\n\t\t\t\tS_H1= 1, S_H2= 2, S_H3= 3, S_H4= 4, S_H5= 5, S_H6= 6,\t// Initial hash of block header (khash)\n\t\t\t\tS_I1= 7, S_I2= 8, S_I3= 9, S_I4=10, S_I5=11, S_I6=12,\t// IPAD hash (ihash)\n\t\t\t\tS_O1=13, S_O2=14, S_O3=15,\t\t\t\t\t\t\t\t// OPAD hash (ohash)\n\t\t\t\tS_B1=16, S_B2=17, S_B3=18, S_B4=19, S_B5=20, S_B6=21,\t// Iterate blocks\n\t\t\t\tS_XX=22,\t\t\t\t\t\t\t\t\t\t\t\t// Possibly superfluous (go straight to S_IDLE)\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 (reuses S_H1 to S_H6 for khash, alternatively could piplenine value)\n\t\t\t\tS_R1=23, S_R2=24, S_R3=25, S_R4=26, S_R5=27, S_R6=28,\t// Final PBKDF2_SHA256_80_128_32\n\t\t\t\tS_R7=29, S_R8=30, S_R9=31, S_R10=32, S_R11=33, S_R12=34,\n\t\t\t\tS_R13=35, S_R14=36, S_R15=37, S_R16=38, S_R17=39, S_R18=40;\n\t\t\t\t\n\treg [5:0] state = S_IDLE;\n\treg mode = 0;\t// 0=PBKDF2_SHA256_80_128, 1=PBKDF2_SHA256_80_128_32\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tSet_SMixInRdy <= 1'b0;\t// Ugly hack, these are overriden below\n\t\tClr_SMixOutRdy <= 1'b0;\n\t\tgolden_nonce_match <= 1'b0;\t// Default to reset\n\t\t\n\t\tif (reset == 1'b1)\n\t\t\tstate <= S_IDLE;\n\t\telse\n\t\tbegin\n\t\t\tcase (state)\n\t\t\t\tS_IDLE: begin\n\t\t\t\t\tif (SMixOutRdy ||\t// Process output\n\t\t\t\t\t\t!SMixInRdy)\t\t// Process input unless already done\n\t\t\t\t\tbegin\n\t\t\t\t\t\t// Both cases use same initial calculaton of khash (its not worth trying to reuse previous khash\n\t\t\t\t\t\t// for the second case as we're not constrained by SHA256 timing)\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Block header is passwd (used as key)\n\t\t\t\t\t\tblockcnt <= 32'd1;\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (SMixOutRdy)\t\t\t\t// Give preference to output\n\t\t\t\t\t\t\tmode <= 1'b1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tmode <= 1'b0;\n\t\t\t\t\t\tstate <= S_H1;\n\t\t\t\t\tend\n\t\t\t\tend\n\n\t\t\t\t// Hash the block header (result is khash)\n\t\t\t\tS_H1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H3;\n\t\t\t\tend\n\t\t\t\tS_H3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Hash last 16 bytes of header including nonce and padded to 64 bytes with 1, zeros and length\n\t\t\t\t\t\t// NB this sequence is used for both input and final PBKDF2_SHA256, hence switch nonce on mode\n\t\t\t\t\t\trx_input <= { 384'h000002800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tmode ? nonce_2 : nonce, data3[95:0] };\n\t\t\t\t\t\tstate <= S_H4;\n\t\t\t\tend\n\t\t\t\tS_H4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_H5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_H5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_H6;\n\t\t\t\tend\n\t\t\t\tS_H6: begin\t// Sync hash\n\t\t\t\t\t\tkhash <= tx_hash;\t// Save for OPAD hash\n\t\t\t\t\t\t// Setup for IPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h3636363636363636363636363636363636363636363636363636363636363636 ,\n\t\t\t\t\t\t\t\t\t\ttx_hash ^ 256'h3636363636363636363636363636363636363636363636363636363636363636 };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tif (mode)\n\t\t\t\t\t\t\tstate <= S_R1;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tstate <= S_I1;\n\t\t\t\tend\n\n\t\t\t\t// IPAD hash\n\t\t\t\tS_I1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I3;\n\t\t\t\tend\n\t\t\t\tS_I3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { data2, data1 };\t// Passwd (used as message)\n\t\t\t\t\t\tstate <= S_I4;\n\t\t\t\tend\n\t\t\t\tS_I4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_I5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_I5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_I6;\n\t\t\t\tend\n\t\t\t\tS_I6: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O1;\n\t\t\t\tend\n\n\t\t\t\t// OPAD hash\n\t\t\t\tS_O1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_O2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_O2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_O3;\n\t\t\t\tend\n\t\t\t\tS_O3: begin\t// Sync hash\n\t\t\t\t\t\tohash <= tx_hash;\t\t\t\t// Save result\n\t\t\t\t\t\t// Setup for block iteration\n\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t// TODO hardwire top 29 bits of blockcnt as zero\n\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\tblockcnt, nonce, data3[95:0] };\n\t\t\t\t\t\tblockcnt <= blockcnt + 1;\t\t// Increment for next time\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\tend\n\n\t\t\t\t// Block iteration (4 cycles)\n\t\t\t\tS_B1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B3;\n\t\t\t\tend\n\t\t\t\tS_B3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= ohash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, tx_hash };\n\t\t\t\t\t\tstate <= S_B4;\n\t\t\t\tend\n\t\t\t\tS_B4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_B5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_B5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_B6;\n\t\t\t\tend\n\t\t\t\tS_B6: begin\t// Shift output into X buffer from MSB->LSB\n\t\t\t\t\t\tXbuf[255:0] <= Xbuf[511:256];\n\t\t\t\t\t\tXbuf[511:256] <= Xbuf[767:512];\n\t\t\t\t\t\tXbuf[767:512] <= Xbuf[1023:768];\n\t\t\t\t\t\tXbuf[1023:768] <= tx_hash;\n\t\t\t\t\t\t// NB nonce is incremented in SMIX FSM\n\n\t\t\t\t\t\tif (blockcnt == 5)\n\t\t\t\t\t\t\tstate <= S_XX;\t// Done\n\t\t\t\t\t\telse begin\n\t\t\t\t\t\t\t// Setup for next block\n\t\t\t\t\t\t\trx_state <= ihash;\n\t\t\t\t\t\t\trx_input <= { 352'h000004a000000000000000000000000000000000000000000000000000000000000000000000000080000000,\n\t\t\t\t\t\t\t\t\t\t\tblockcnt, nonce, data3[95:0] };\n\t\t\t\t\t\t\tblockcnt <= blockcnt + 1;\t\t// Increment for next time\n\t\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\t\tstate <= S_B1;\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_XX: begin\n\t\t\t\t\t\t// State is possibly superfluous (go straight to S_IDLE from S_B6)\n\t\t\t\t\t\t// SMixInRdy <= 1;\t\t// Original\n\t\t\t\t\t\tSet_SMixInRdy <= 1;\t// Ugly hack\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\tend\n\t\t\t\t\n\t\t\t\t// Final PBKDF2_SHA256_80_128_32 NB Entered from S_H6 via mode flag\n\t\t\t\t// Similar to S_I0 but using MixOut as salt and finalblk padding\n\t\t\t\tS_R1: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R2;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R2: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R3;\n\t\t\t\tend\n\t\t\t\tS_R3: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[511:0];\t\t// Salt (first block)\n\t\t\t\t\t\tstate <= S_R4;\n\t\t\t\tend\n\t\t\t\tS_R4: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R5;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R5: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R6;\n\t\t\t\tend\n\t\t\t\tS_R6: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= MixOutRewire[1023:512];\t\t// Salt (second block)\n\t\t\t\t\t\tstate <= S_R7;\n\t\t\t\tend\n\t\t\t\tS_R7: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R8;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R8: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R9;\n\t\t\t\tend\n\t\t\t\tS_R9: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\t// Final padding\n\t\t\t\t\t\trx_input <= 512'h00000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001;\n\t\t\t\t\t\tstate <= S_R10;\n\t\t\t\tend\n\t\t\t\tS_R10: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R11;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R11: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R12;\n\t\t\t\tend\n\t\t\t\tS_R12: begin\t// Sync hash\n\t\t\t\t\t\tihash <= tx_hash;\t\t\t\t// Save (reuse ihash)\n\t\t\t\t\t\t// Setup for OPAD hash\n\t\t\t\t\t\trx_state <= 256'h5be0cd191f83d9ab9b05688c510e527fa54ff53a3c6ef372bb67ae856a09e667;\n\t\t\t\t\t\trx_input <= { 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c ,\n\t\t\t\t\t\t\t\t\t\tkhash ^ 256'h5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c };\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R13;\n\t\t\t\tend\n\t\t\t\tS_R13: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R14;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R14: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R15;\n\t\t\t\tend\n\t\t\t\tS_R15: begin\t// Sync hash\n\t\t\t\t\t\trx_state <= tx_hash;\n\t\t\t\t\t\trx_input <= { 256'h0000030000000000000000000000000000000000000000000000000080000000, ihash };\n\t\t\t\t\t\tstate <= S_R16;\n\t\t\t\tend\n\t\t\t\tS_R16: begin\t// Waiting for result\n\t\t\t\t\tcnt <= cnt + 6'd1;\n\t\t\t\t\tif (cnt == 6'd63)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tcnt <= 6'd0;\n\t\t\t\t\t\tstate <= S_R17;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tS_R17: begin\t// Sync hash\n\t\t\t\t\t\tstate <= S_R18;\n\t\t\t\tend\n\t\t\t\tS_R18: begin\t// Sync hash\n\t\t\t\t\t\t// Check for golden nonce in tx_hash\n\t\t\t\t\t\t`ifdef SIM\n\t\t\t\t\t\t\tfinal_hash <= tx_hash;\t\t// For debug\n\t\t\t\t\t\t`endif\n\t\t\t\t\t\t// Could optimise target calc ...\n\t\t\t\t\t\tif ( { tx_hash[231:224], tx_hash[239:232], tx_hash[247:240], tx_hash[255:248] } < target)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tgolden_nonce <= nonce_2;\n\t\t\t\t\t\t\tgolden_nonce_match <= 1'b1;\t// Set flag (for one cycle only, see default at top)\n\t\t\t\t\t\tend\n\t\t\t\t\t\tstate <= S_IDLE;\n\t\t\t\t\t\tmode <= 0;\n\t\t\t\t\t\t// SMixOutRdy <= 1'b0;\t// Original version\n\t\t\t\t\t\tClr_SMixOutRdy <= 1'b1;\t// Ugly hack\n\t\t\t\tend\n\t\t\tendcase\t\n\t\tend\n\tend\n\n\t// Convert Xbuf to little-endian word format to match scrypt.c as its easier to debug it\n\t// this way rather than recoding the SMix salsa to work with original buffer\n\n\twire [1023:0] X;\n\t`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\tgenvar i;\n\tgenerate\n\tfor (i = 0; i < 32; i = i + 1) begin : Xrewire\n\t\twire [31:0] tmp;\n\t\tassign tmp = Xbuf[`IDX(i)];\n\t\tassign X[`IDX(i)] = { tmp[7:0], tmp[15:8], tmp[23:16], tmp[31:24] };\n\n\t\t// Also need to do MixOut\n\t\twire [31:0] mix;\n\t\tassign mix = MixOut[`IDX(i)];\n\t\tassign MixOutRewire[`IDX(i)] = { mix[7:0], mix[15:8], mix[23:16], mix[31:24] };\n\tend\n\tendgenerate\n\n\t// Salsa Mix FSM (handles both loading of the scratchpad ROM and the subsequent processing)\n\n\t// NB apparently this is poor coding style (sorry, I'm just a newbie here), but its working so\n\t// I'm not going to change it now (perhaps in a future version). It could also do with optimisation\n\t// as this IS on the critical path for throughput, unlike SHA256. It may be possible to remove some\n\t// latency for significant performance boost. SPECIFICALLY it may be possible to use 4 cycles rather\n\t// than 5 per write, and similarily for R_MIX\n\n\tparameter R_IDLE=0, R_WRITE=1, R_MIX=2, R_INT=3;\n\treg [1:0] mstate = R_IDLE;\n\treg [10:0] cycle = 11'd0;\n\treg [5:0] mcount = 5'd0;\t// Salsa latency\n\treg doneROM = 1'd0;\t\t\t// Yes ROM, as its referred thus in the salsa docs. Maybe rename doneWRITE?\n\treg mixfeedback = 1'b0;\n\treg addrsourceMix = 1'b0;\t// Another HACK\n\n\treg [511:0] X0;\n\treg [511:0] X1;\n\t`ifdef HALFRAM\n\t\treg [511:0] X0Save;\t\t// Save old value during interpolation\n\t\treg [511:0] X1Save;\n\t\treg\toddAddr = 1'b0;\t\t// Flag for odd addresses to interpolate\n\t`endif\n\twire [511:0] Xmix;\n\n\t// NB writeaddr is cycle counter in R_WRITE so use full size regardless of HALFRAM mode\n\treg [9:0] writeaddr = 10'd0;\n\t\n\t// ALTRAM Max is 256 bit width, so use four\n\t// Ram is registered on inputs vis ram_addr, ram_din and ram_wren\n\t// Output is unregistered, OLD data on write (less delay than NEW??)\n\t\n\t`ifdef HALFRAM\n\t\tparameter ADDRBITS = 9;\n\t`else\n\t\tparameter ADDRBITS = 10;\n\t`endif\n\n\twire [ADDRBITS-1:0]ram_addr;\n\twire [255:0]ram1_din;\n\twire [255:0]ram1_dout;\n\twire [255:0]ram2_din;\n\twire [255:0]ram2_dout;\n\twire [255:0]ram3_din;\n\twire [255:0]ram3_dout;\n\twire [255:0]ram4_din;\n\twire [255:0]ram4_dout;\n\twire [1023:0]ramout;\n\n\treg ram_wren;\n\twire ram_clk;\n\tassign ram_clk = hash_clk;\t// Uses same clock as hasher for now\n\t\n\t`ifdef HALFRAM\n\t\t// This is the half scratchpad version\n\t\tassign ram_addr = addrsourceMix ? Xmix[9:1] : writeaddr[9:1];\t// LSB is ignored\n\t`else\n\t\t// This is the full scratchpad version\n\t\tassign ram_addr = addrsourceMix ? Xmix[9:0] : writeaddr;\n\t`endif\n\tram # (.ADDRBITS(ADDRBITS)) ram1_blk (ram_addr, ram_clk, ram1_din, ram_wren, ram1_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram2_blk (ram_addr, ram_clk, ram2_din, ram_wren, ram2_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram3_blk (ram_addr, ram_clk, ram3_din, ram_wren, ram3_dout);\n\tram # (.ADDRBITS(ADDRBITS)) ram4_blk (ram_addr, ram_clk, ram4_din, ram_wren, ram4_dout);\n\tassign ramout = { ram4_dout, ram3_dout, ram2_dout, ram1_dout };\t// Unregistered output\n\tassign { ram4_din, ram3_din, ram2_din, ram1_din } = { X1, X0} ;\t// Registered input\n\n\t// Salsa unit\n\t\n\tsalsa salsa_blk (hash_clk, mixfeedback, X0, X1, Xmix);\n\n\t// Salsa FSM (see note above about bad coding style)\n\t\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tSet_SMixOutRdy <= 1'b0;\n\t\tClr_SMixInRdy <= 1'b0;\n\t\t`ifdef HALFRAM\n\t\t\toddAddr <= Xmix[0];\t\t// Flag odd addresses (for use in next cycle due to ram latency)\n\t\t`endif\n\t\t`ifdef ICARUS\n\t\tif (loadnonce)\t\t\t\t// Separate clock domains means comparison is unsafe\n\t\t`else\n\t\tif (loadnonce || (nonce_prevous_load != data3[127:96]))\n\t\t`endif\n\t\tbegin\n\t\t\t`ifdef NOMULTICORE\n\t\t\t\tnonce <= data3[127:96];\t// Supports loading of initial nonce for test purposes (potentially\n\t\t\t\t\t\t\t\t\t\t// overriden by the increment below, but this occurs very rarely)\n\t\t\t\t\t\t\t\t\t\t// This also gives a consistent start point when we send the first work\n\t\t\t\t\t\t\t\t\t\t// packet (but ONLY the first one since its always zero) when using live data\n\t\t\t\t\t\t\t\t\t\t// as we initialise nonce_prevous_load to ffffffff\n\t\t\t`else\n\t\t\t\tnonce_cnt <= data3[123:96];\t// The 4 msb of nonce are hardwired in MULTICORE mode, so test nonce\n\t\t\t\t\t\t\t\t\t\t\t// needs to be <= 0fffffff and will only match in the 0 core\n\t\t\t`endif\n\t\t\t`ifndef ICARUS\n\t\t\tnonce_prevous_load <= data3[127:96];\n\t\t\t`endif\n\t\tend\n\t\tif (reset == 1'b1)\n\t\t\tmstate <= R_IDLE;\n\t\telse\n\t\tbegin\n\t\t\tcase (mstate)\n\t\t\t\tR_IDLE: begin\n\t\t\t\t\twriteaddr <= 0;\n\t\t\t\t\tmcount <= 0;\n\t\t\t\t\tX0 <= X[511:0];\n\t\t\t\t\tX1 <= X[1023:512];\n\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\taddrsourceMix <= 1'b0;\n\t\t\t\t\tif (SMixInRdy)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tmstate <= R_WRITE;\n\t\t\t\t\t\t\tdoneROM <= 1'b0;\n\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t// Initial write cycle\n\t\t\t\t\t\t\t// SMixInRdy <= 0;\t\t// Original version\n\t\t\t\t\t\t\tClr_SMixInRdy <= 1;\t\t// Ugly hack\n\t\t\t\t\t\t\t// Save and increment nonce (NB done here not in SHA256 FSM)\n\t\t\t\t\t\t\tnonce_1 <= nonce;\n\t\t\t\t\t\t\t`ifndef NOMULTICORE\n\t\t\t\t\t\t\t\tnonce_cnt <= nonce_cnt + 28'd1;\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tnonce <= nonce + 32'd1;\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_WRITE: begin\n\t\t\t\t\tmcount <= mcount + 6'd1;\n\t\t\t\t\tram_wren <= 0;\t\t// Default state, overriden below at mcount==9\n\t\t\t\t\t// 8 stages since salsa takes 4 clock cycles. NB This minimises clock cycles, but adds to\n\t\t\t\t\t// the propagation delay in the salsa. The alternative of adding a cycle or two of latency to\n\t\t\t\t\t// reduce propagation delay is SLOWER due to the extra clocks needed.\n\t\t\t\t\t// Write to ROM every 2nd cycle (NB we are writing previous data here)\n\t\t\t\t\t// NB One extra cycle is performed after ROM is complete to update X0,X1 to inital state for R_MIX\n\t\t\t\t\tif (mcount==0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\t\tif (writeaddr==1023)\n\t\t\t\t\t\t\tdoneROM <= 1'b1;\t\t\t// Need to do one more cycle to update X0,X1\n\t\t\t\t\t\twriteaddr <= writeaddr + 10'd1;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount==4)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount == 3 || mcount == 7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tX0 <= X1;\n\t\t\t\t\t\tX1 <= Xmix;\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount == 6 && doneROM)\t\t\t// NASTY HACK ... preset the address source one cycle early\n\t\t\t\t\t\taddrsourceMix <= 1'b1;\n\t\t\t\t\tif (mcount == 7)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tif (doneROM)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\tcycle <= 0;\n\t\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\t\tend\n\t\t\t\t\t\telse\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// NB the !doneROM test is superfluous here as its in the else clause of if(doneROM)\n\t\t\t\t\t\t\t`ifdef HALFRAM\n\t\t\t\t\t\t\t\tif (!doneROM && !writeaddr[0])\t// Do not write on odd cycles (half scratchpad)\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Since registered we preset this here\n\t\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t\tif (!doneROM)\n\t\t\t\t\t\t\t\t\tram_wren <= 1'b1;\t\t\t// Since registered we preset this here\n\t\t\t\t\t\t\t`endif\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\tR_MIX: begin\n\t\t\t\t\t// Entered with mixfeedback == 0 (set at mcount==7 above)\n\t\t\t\t\t// NB There is an extra step here cf R_WRITE above to read ram data hence 9 not 8 stages.\n\t\t\t\t\t// The longest chain is from mixfeedback to ram address input (since XMix is not registered),\n\t\t\t\t\t// again as noted above, extra register stages would simply reduce throughput.\n\t\t\t\t\tmcount <= mcount + 5'd1;\n\t\t\t\t\tif (mcount == 0)\n\t\t\t\t\tbegin\n\t\t\t\t\t\t`ifdef HALFRAM\n\t\t\t\t\t\t\tif (oddAddr)\t\t\t// Set in previous cycle\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\tX0Save <= X0;\n\t\t\t\t\t\t\t\tX0 <= ramout[511:0];\n\t\t\t\t\t\t\t\tX1Save <= X1;\n\t\t\t\t\t\t\t\tX1 <= ramout[1023:512];\n\t\t\t\t\t\t\t\tmixfeedback <= 0;\n\t\t\t\t\t\t\t\tmstate <= R_INT;\t// Interpolate\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t\t// Perhaps we can reuse the xor's in the salsa module here?\n\t\t\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\t\t\tX0 <= X0 ^ ramout[511:0];\n\t\t\t\t\t\t\t\tX1 <= X1 ^ ramout[1023:512];\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t`else\n\t\t\t\t\t\t\t// Perhaps we can reuse the xor's in the salsa module here?\n\t\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\t\t X0 <= X0 ^ ramout[511:0];\n\t\t\t\t\t\t\t X1 <= X1 ^ ramout[1023:512];\n\t\t\t\t\t\t`endif\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount==1 || mcount==5)\n\t\t\t\t\t\tmixfeedback <= 1;\n\t\t\t\t\tif (mcount == 4 || mcount == 8)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 1'b0;\n\t\t\t\t\t\tX0 <= X1;\n\t\t\t\t\t\tX1 <= Xmix;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount == 8)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmcount <= 0;\n\t\t\t\t\t\tcycle <= cycle + 11'd1;\n\t\t\t\t\t\tif (cycle == 1023)\n\t\t\t\t\t\tbegin\n\t\t\t\t\t\t\t// Pipeline the result so we can start processing the next X input\n\t\t\t\t\t\t\tMixOut <= { Xmix, X1 };\n\t\t\t\t\t\t\t// Flag the SHA256 FSM to start final PBKDF2_SHA256_80_128_32\n\t\t\t\t\t\t\t// SMixOutRdy <= 1'b1;\t\t// Original version\n\t\t\t\t\t\t\tSet_SMixOutRdy <= 1'b1;\t\t// Ugly hack\n\t\t\t\t\t\t\tnonce_2 <= nonce_1;\n\t\t\t\t\t\t\tmstate <= R_IDLE;\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t`ifdef HALFRAM\n\t\t\t\tR_INT: begin\n\t\t\t\t\t// Interpolate scratchpad for odd addresses\n\t\t\t\t\t// Mcount has already been incremented in R_MIX\n\t\t\t\t\tmcount <= mcount + 6'd1;\n\t\t\t\t\tif (mcount==1 || mcount==5)\n\t\t\t\t\t\tmixfeedback <= 1'b1;\n\t\t\t\t\tif (mcount == 4)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 0;\n\t\t\t\t\t\tX0 <= X1;\n\t\t\t\t\t\tX1 <= Xmix;\n\t\t\t\t\tend\n\t\t\t\t\tif (mcount == 8)\n\t\t\t\t\tbegin\n\t\t\t\t\t\tmixfeedback <= 0; // Required\n\t\t\t\t\t\tX0 <= X1 ^ X0Save;\t// Same result as step 0 in R_MIX\n\t\t\t\t\t\tX1 <= Xmix ^ X1Save;\n\t\t\t\t\t\tmcount <= 1;\t\t// Skip 0 since done above\n\t\t\t\t\t\tmstate <= R_MIX;\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\t\t`endif\n\t\t\tendcase\n\t\tend\n\tend\n\nendmodule"
  },
  {
    "path": "source/ltcminer.v",
    "content": "/* ltcminer.v\n*\n* Copyright (c) 2013 kramble\n* Parts copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`ifdef NOLEDS\n\tmodule ltcminer (osc_clk);\t\t// Version without LEDs for DE2-115\n`else\n\tmodule ltcminer (osc_clk, LEDS_out);\n`endif\n\t\n`ifdef SPEED_MHZ\n\tparameter SPEED_MHZ = `SPEED_MHZ;\n`else\n\tparameter SPEED_MHZ = 25;\n`endif\n\n// LOCAL_MINERS determinse the number of cores (the terminology is consistent with the LX150 port)\n`ifdef LOCAL_MINERS\n\tparameter LOCAL_MINERS = `LOCAL_MINERS;\n`else\n\tparameter LOCAL_MINERS = 1;\n`endif\n\n\tinput osc_clk;\n`ifndef NOLEDS\n\toutput reg [7:0]LEDS_out;\t\t\t// Optional progress indicator\n`endif\n\n\twire hash_clk;\n\t`ifndef SIM\n\t\tmain_pll #(.SPEED_MHZ(SPEED_MHZ)) pll_blk (osc_clk, hash_clk);\n\t`else\n\t \tassign hash_clk = osc_clk;\n\t`endif\n\n// Virtual wire is now done here rather than in hashcore so as to support MULTICORE\t\n\n`ifndef SIM\n\t// 80 byte block header (NB this implimetation does not use midstate)\n\treg [255:0] data1 = 256'd0;\n\treg [255:0] data2 = 256'd0;\n\treg [127:0] data3 = 128'd0;\n\t// final_hash=553a4b69b43913a61b42013ce210f713eaa7332e48cda1bdf3b93b10161d0876 (NOT a match)\n`else\n\t// Test data (MATCH nonce 0000318f)\n\treg [255:0] data1 = 256'h18e7b1e8eaf0b62a90d1942ea64d250357e9a09c063a47827c57b44e01000000;\n\treg [255:0] data2 = 256'hc791d4646240fc2a2d1b80900020a24dc501ef1599fc48ed6cbac920af755756;\n\treg [127:0] data3 = 128'h0000318f7e71441b141fe951b2b0c7df;\t// NB 0000318f is loaded into nonce\n\t// final_hash=b303000066bd9f068aa115339cfd01cd94121ef65b2ff4d7d3796b738a174f7b (MATCH at target=000007ff/diff=32)\n`endif\n\t\n\treg [31:0] target = 31'h000007ff;\t// Default to diff=32 for sane startup, this is overwritten by virtual_wire\n\n\twire [31:0]golden_nonce_out;\n\twire [31:0] nonce_out;\n\twire loadnonce = 1'b0;\t\t\t\t// Only used in serial comms interface\n\twire [LOCAL_MINERS*32-1:0] golden_nonce_i;\n\twire [LOCAL_MINERS-1:0] golden_nonce_match;\n\n\tgenerate\n\t\tgenvar i;\n\t\tfor (i = 0; i < LOCAL_MINERS; i = i + 1)\n\t\tbegin: for_local_miners\n\t\t\twire [31:0] nonce_out_i;\n\t\t\twire [3:0] nonce_core = i;\n\t\t\n\t\t\thashcore M (hash_clk, data1, data2, data3, target, nonce_core, nonce_out_i, golden_nonce_i[(i+1)*32-1:i*32], golden_nonce_match[i], loadnonce);\n\t\t\t\n\t\t\tif (i==0)\n\t\t\t\tassign nonce_out = nonce_out_i;\t// NB mining script will under-report hash rate by factor of LOCAL_MINERS\n\t\t\t\t\t\t\t\t\t\t\t\t// TODO correctabe by a simple shift here of log2(LOCAL-MINERS)\n\t\tend\n\tendgenerate\n\t\n\t// Simple queue as virtual_wire just reports current value of golden_nonce\n\t\n\t// What I want here is a parameterised, one-hot (priority) selected multiplexor, but since\n\t// my verilog is not very good, I'll just reuse the hub_core code instead\n\t\n\treg [LOCAL_MINERS-1:0]new_nonces_flag = 0;\n   \n\tfunction integer clog2;\t\t// Courtesy of razorfishsl, replaces $clog2() - needed for ISE < 14.1\n\tinput integer value;\n\tbegin\n\t\tvalue = value-1;\n\t\tfor (clog2=0; value>0; clog2=clog2+1)\n\t\tvalue = value>>1;\n\tend\n\tendfunction\n\n\treg [clog2(LOCAL_MINERS)+1:0] port_counter = 0;\n\treg [LOCAL_MINERS*32-1:0] nonces_shifted = 0;\n\tassign golden_nonce_out = nonces_shifted[31:0];\n\n\t// Mark nonces to be cleared during next clock cycle\n\treg [LOCAL_MINERS-1:0] clear_nonces = 0;\n\n\talways @(posedge hash_clk)\n\tbegin\n\t\t// Raise flags when new nonces appear; lower those that have been sent\n\t\tnew_nonces_flag <= (new_nonces_flag & ~clear_nonces) | golden_nonce_match;\n\n\t\tif (port_counter == LOCAL_MINERS-1)\n\t\t\tport_counter <= 0;\n\t\telse\n\t\t\tport_counter <= port_counter + 1'd1;\n\t\t\n\t\t// kramble - the optimiser removes all but the low 32 bits of nonces_shifted since\n\t\t// the following code implements a multiplexor on nonces input, NOT an actual shifter.\n\t\tif (new_nonces_flag[port_counter])\n\t\tbegin\n\t\t\tnonces_shifted <= golden_nonce_i >> port_counter*32;\n\t\t\tclear_nonces[port_counter] <= 1;\n\t\tend\n\t\telse \n\t\tbegin\n\t\t\tclear_nonces <= 0;\n\t\tend\n\tend\n\t\n\t`ifndef SIM\n\n\t//// Virtual Wire Control\n\twire [255:0] data1_vw;\n\twire [255:0] data2_vw;\n\twire [127:0] data3_vw;\t\t// 96 bits actually used, the extra 32 are the nonce, normally all zeros but for\n\t\t\t\t\t\t\t\t// testing we can supply a nonce which will be loaded. Some pools set a non-zero nonce\n\t\t\t\t\t\t\t\t// in getwork (which we will load), but this is of no consequence to live mining.\n\twire [31:0] target_vw;\t\t// This depends on the pool, variable diff pools will update the target dynamically\n\n\tvirtual_wire # (.PROBE_WIDTH(0), .WIDTH(256), .INSTANCE_ID(\"DAT1\")) data1_vw_blk(.probe(), .source(data1_vw));\n\tvirtual_wire # (.PROBE_WIDTH(0), .WIDTH(256), .INSTANCE_ID(\"DAT2\")) data2_vw_blk(.probe(), .source(data2_vw));\n\tvirtual_wire # (.PROBE_WIDTH(0), .WIDTH(128), .INSTANCE_ID(\"DAT3\")) data3_vw_blk(.probe(), .source(data3_vw));\n\tvirtual_wire # (.PROBE_WIDTH(0), .WIDTH(32), .INSTANCE_ID(\"TARG\")) target_vw_blk(.probe(), .source(target_vw));\n\n\talways @ (posedge hash_clk)\n\tbegin\n\t\tdata1 <= data1_vw;\n\t\tdata2 <= data2_vw;\n\t\tdata3 <= data3_vw;\n\t\ttarget <= target_vw;\n\tend\n\n\t//// Virtual Wire Output\n\t\n\tvirtual_wire # (.PROBE_WIDTH(32), .WIDTH(0), .INSTANCE_ID(\"GNON\")) golden_nonce_vw_blk (.probe(golden_nonce_out), .source());\n\tvirtual_wire # (.PROBE_WIDTH(32), .WIDTH(0), .INSTANCE_ID(\"NONC\")) nonce_vw_blk (.probe(nonce_out), .source());\n\n\t`endif\n\t\n\n`ifndef NOLEDS\n\t// Optional LED progress indicator\n\talways @(posedge hash_clk) begin\n\t`ifdef INVERTLEDS\n\t\tLEDS_out <= ~nonce_out[15:8];\t\t// Inverted for BeMicro\n\t`else\n\t\tLEDS_out <= nonce_out[15:8];\n\t`endif\n\tend\n`endif\n\nendmodule\n"
  },
  {
    "path": "source/salsa.v",
    "content": "/* salsa.v ... yes its crude, I'm not very good at verilog\n*\n* Copyright (c) 2013 kramble\n* Derived from scrypt.c Copyright 2009 Colin Percival, 2011 ArtForz\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n`timescale 1ns/1ps\n\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\nmodule salsa (clk, feedback, B, Bx, Bo);\n\n// Latency 4 clock cycles, approx 40nS propagation delay (SLOW!), but pipelining\n// is pointless as we have nothing else to fill the pipe with, so it actually\n// REDUCES the throughput due to the setup/propagation delays of the registers.\n\ninput clk;\ninput feedback;\ninput [511:0]B;\ninput [511:0]Bx;\n// output reg [511:0]Bo;\t// Output is registered\noutput [511:0]Bo;\t\t\t// Output is async\n\nwire [511:0]xx;\t\t\t// Initial xor\n\n/*\n// Non-feedback version\n\nwire [511:0]x1;\t\t\t// Salasa core outputs\nwire [511:0]x2;\nwire [511:0]x3;\nwire [511:0]xr;\n\n// Four salsa iterations. NB use registered salsa_core so 4 clock cycles.\nsalsa_core salsa1 (clk, xx, x1);\nsalsa_core salsa2 (clk, x1, x2);\nsalsa_core salsa3 (clk, x2, x3);\nsalsa_core salsa4 (clk, x3, xr);\n*/\n\n// Feedback version\nwire [511:0]xr;\nreg [511:0]xrd;\n//salsa_core salsa1 (clk, feedback ? xr : xx, xr);\t// unregistered xr\nsalsa_core salsa1 (clk, feedback ? xrd : xx, xr);\t// registered xrd\n\ngenvar i;\ngenerate\n\tfor (i = 0; i < 16; i = i + 1) begin : XX\n\t\t// Initial XOR. NB this adds to the propagation delay of the first salsa, may want register it.\n\t\tassign xx[`IDX(i)] = B[`IDX(i)] ^ Bx[`IDX(i)];\n\t\t// Final sum. This could is subsumed into the final salsa to save a clock.\n//\t\talways @ (posedge clk)\n//\t\tbegin\n//\t\t\tBo[`IDX(i)] <= xx[`IDX(i)] + xr[`IDX(i)];\n//\t\tend\n\t\tassign Bo[`IDX(i)] = xx[`IDX(i)] + xr[`IDX(i)];\t// Async output (NB bypasses xrd register)\n\tend\nendgenerate\n\nalways @ (posedge clk)\n\txrd <= xr;\n\nendmodule\n\nmodule salsa_core (clk, xx, out);\n\ninput clk;\ninput [511:0]xx;\n// output reg [511:0]out;\t\t// Output is registered\noutput [511:0]out;\t\t\t\t// Output is unregistered\n\n// This is clunky due to my lack of verilog skills but it works so elegance can come later\n\nwire [31:0]c00;\t\t\t// Column results\nwire [31:0]c01;\nwire [31:0]c02;\nwire [31:0]c03;\nwire [31:0]c04;\nwire [31:0]c05;\nwire [31:0]c06;\nwire [31:0]c07;\nwire [31:0]c08;\nwire [31:0]c09;\nwire [31:0]c10;\nwire [31:0]c11;\nwire [31:0]c12;\nwire [31:0]c13;\nwire [31:0]c14;\nwire [31:0]c15;\n\nwire [31:0]r00;\t\t\t// Row results\nwire [31:0]r01;\nwire [31:0]r02;\nwire [31:0]r03;\nwire [31:0]r04;\nwire [31:0]r05;\nwire [31:0]r06;\nwire [31:0]r07;\nwire [31:0]r08;\nwire [31:0]r09;\nwire [31:0]r10;\nwire [31:0]r11;\nwire [31:0]r12;\nwire [31:0]r13;\nwire [31:0]r14;\nwire [31:0]r15;\n\nwire [31:0]c00s;\t\t\t// Column sums\nwire [31:0]c01s;\nwire [31:0]c02s;\nwire [31:0]c03s;\nwire [31:0]c04s;\nwire [31:0]c05s;\nwire [31:0]c06s;\nwire [31:0]c07s;\nwire [31:0]c08s;\nwire [31:0]c09s;\nwire [31:0]c10s;\nwire [31:0]c11s;\nwire [31:0]c12s;\nwire [31:0]c13s;\nwire [31:0]c14s;\nwire [31:0]c15s;\n\nwire [31:0]r00s;\t\t\t// Row sums\nwire [31:0]r01s;\nwire [31:0]r02s;\nwire [31:0]r03s;\nwire [31:0]r04s;\nwire [31:0]r05s;\nwire [31:0]r06s;\nwire [31:0]r07s;\nwire [31:0]r08s;\nwire [31:0]r09s;\nwire [31:0]r10s;\nwire [31:0]r11s;\nwire [31:0]r12s;\nwire [31:0]r13s;\nwire [31:0]r14s;\nwire [31:0]r15s;\n\n/* From scrypt.c\n\n#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))\n\tfor (i = 0; i < 8; i += 2) {\n\t\t// Operate on columns\n\t\tx04 ^= R(x00+x12, 7);\tx09 ^= R(x05+x01, 7);\tx14 ^= R(x10+x06, 7);\tx03 ^= R(x15+x11, 7);\n\t\tx08 ^= R(x04+x00, 9);\tx13 ^= R(x09+x05, 9);\tx02 ^= R(x14+x10, 9);\tx07 ^= R(x03+x15, 9);\n\t\tx12 ^= R(x08+x04,13);\tx01 ^= R(x13+x09,13);\tx06 ^= R(x02+x14,13);\tx11 ^= R(x07+x03,13);\n\t\tx00 ^= R(x12+x08,18);\tx05 ^= R(x01+x13,18);\tx10 ^= R(x06+x02,18);\tx15 ^= R(x11+x07,18);\n\n\t\t// Operate on rows\n\t\tx01 ^= R(x00+x03, 7);\tx06 ^= R(x05+x04, 7);\tx11 ^= R(x10+x09, 7);\tx12 ^= R(x15+x14, 7);\n\t\tx02 ^= R(x01+x00, 9);\tx07 ^= R(x06+x05, 9);\tx08 ^= R(x11+x10, 9);\tx13 ^= R(x12+x15, 9);\n\t\tx03 ^= R(x02+x01,13);\tx04 ^= R(x07+x06,13);\tx09 ^= R(x08+x11,13);\tx14 ^= R(x13+x12,13);\n\t\tx00 ^= R(x03+x02,18);\tx05 ^= R(x04+x07,18);\tx10 ^= R(x09+x08,18);\tx15 ^= R(x14+x13,18);\n\t}\n*/\n\n// cols\n\nassign c04s = xx[`IDX(0)] + xx[`IDX(12)];\nassign c04 = xx[`IDX(4)] ^ { c04s[24:0], c04s[31:25] };\nassign c09s = xx[`IDX(5)] + xx[`IDX(1)];\nassign c09 = xx[`IDX(9)] ^ { c09s[24:0], c09s[31:25] };\nassign c14s = xx[`IDX(10)] + xx[`IDX(6)];\nassign c14 = xx[`IDX(14)] ^ { c14s[24:0], c14s[31:25] };\nassign c03s = xx[`IDX(15)] + xx[`IDX(11)];\nassign c03 = xx[`IDX(03)] ^ { c03s[24:0], c03s[31:25] };\n\nassign c08s = c04 + xx[`IDX(0)];\nassign c08 = xx[`IDX(8)] ^ { c08s[22:0], c08s[31:23] };\nassign c13s = c09 + xx[`IDX(5)];\nassign c13 = xx[`IDX(13)] ^ { c13s[22:0], c13s[31:23] };\nassign c02s = c14 + xx[`IDX(10)];\nassign c02 = xx[`IDX(2)] ^ { c02s[22:0], c02s[31:23] };\nassign c07s = c03 + xx[`IDX(15)];\nassign c07 = xx[`IDX(7)] ^ { c07s[22:0], c07s[31:23] };\n\nassign c12s = c08 + c04;\nassign c12 = xx[`IDX(12)] ^ { c12s[18:0], c12s[31:19] };\nassign c01s = c13 + c09;\nassign c01 = xx[`IDX(1)] ^ { c01s[18:0], c01s[31:19] };\nassign c06s = c02 + c14;\nassign c06 = xx[`IDX(6)] ^ { c06s[18:0], c06s[31:19] };\nassign c11s = c07 + c03;\nassign c11 = xx[`IDX(11)] ^ { c11s[18:0], c11s[31:19] };\n\nassign c00s = c12 + c08;\nassign c00 = xx[`IDX(0)] ^ { c00s[13:0], c00s[31:14] };\nassign c05s = c01 + c13;\nassign c05 = xx[`IDX(5)] ^ { c05s[13:0], c05s[31:14] };\nassign c10s = c06 + c02;\nassign c10 = xx[`IDX(10)] ^ { c10s[13:0], c10s[31:14] };\nassign c15s = c11 + c07;\nassign c15 = xx[`IDX(15)] ^ { c15s[13:0], c15s[31:14] };\n\n// rows\n\nassign r01s = c00 + c03;\nassign r01 = c01 ^ { r01s[24:0], r01s[31:25] };\nassign r06s = c05 + c04;\nassign r06 = c06 ^ { r06s[24:0], r06s[31:25] };\nassign r11s = c10 + c09;\nassign r11 = c11 ^ { r11s[24:0], r11s[31:25] };\nassign r12s = c15 + c14;\nassign r12 = c12 ^ { r12s[24:0], r12s[31:25] };\n\nassign r02s = r01 + c00;\nassign r02 = c02 ^ { r02s[22:0], r02s[31:23] };\nassign r07s = r06 + c05;\nassign r07 = c07 ^ { r07s[22:0], r07s[31:23] };\nassign r08s = r11 + c10;\nassign r08 = c08 ^ { r08s[22:0], r08s[31:23] };\nassign r13s = r12 + c15;\nassign r13 = c13 ^ { r13s[22:0], r13s[31:23] };\n\nassign r03s = r02 + r01;\nassign r03 = c03 ^ { r03s[18:0], r03s[31:19] };\nassign r04s = r07 + r06;\nassign r04 = c04 ^ { r04s[18:0], r04s[31:19] };\nassign r09s = r08 + r11;\nassign r09 = c09 ^ { r09s[18:0], r09s[31:19] };\nassign r14s = r13 + r12;\nassign r14 = c14 ^ { r14s[18:0], r14s[31:19] };\n\nassign r00s = r03 + r02;\nassign r00 = c00 ^ { r00s[13:0], r00s[31:14] };\nassign r05s = r04 + r07;\nassign r05 = c05 ^ { r05s[13:0], r05s[31:14] };\nassign r10s = r09 + r08;\nassign r10 = c10 ^ { r10s[13:0], r10s[31:14] };\nassign r15s = r14 + r13;\nassign r15 = c15 ^ { r15s[13:0], r15s[31:14] };\n\n\nassign out = { r15, r14, r13, r12, r11, r10, r09, r08, r07, r06, r05, r04, r03, r02, r01, r00 };\n\n// Registered output ...\n// wire [511:0]xo;\t\t\t// Rename row results\n// assign xo = { r15, r14, r13, r12, r11, r10, r09, r08, r07, r06, r05, r04, r03, r02, r01, r00 };\n\n// Output is registered, but may want to make it async\n// always @ (posedge clk)\n//\tout <= xo;\n\nendmodule\n"
  },
  {
    "path": "source/sha-256-functions.v",
    "content": "/*\n*\n* Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n*\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n\n`timescale 1ns/1ps\n\nmodule e0 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y = {x[1:0],x[31:2]} ^ {x[12:0],x[31:13]} ^ {x[21:0],x[31:22]};\n\nendmodule\n\n\nmodule e1 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y = {x[5:0],x[31:6]} ^ {x[10:0],x[31:11]} ^ {x[24:0],x[31:25]};\n\nendmodule\n\n\nmodule ch (x, y, z, o);\n\n\tinput [31:0] x, y, z;\n\toutput [31:0] o;\n\n\tassign o = z ^ (x & (y ^ z));\n\nendmodule\n\n\nmodule maj (x, y, z, o);\n\n\tinput [31:0] x, y, z;\n\toutput [31:0] o;\n\n\tassign o = (x & y) | (z & (x | y));\n\nendmodule\n\n\nmodule s0 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y[31:29] = x[6:4] ^ x[17:15];\n\tassign y[28:0] = {x[3:0], x[31:7]} ^ {x[14:0],x[31:18]} ^ x[31:3];\n\nendmodule\n\n\nmodule s1 (x, y);\n\n\tinput [31:0] x;\n\toutput [31:0] y;\n\n\tassign y[31:22] = x[16:7] ^ x[18:9];\n\tassign y[21:0] = {x[6:0],x[31:17]} ^ {x[8:0],x[31:19]} ^ x[31:10];\n\nendmodule\n\n\n"
  },
  {
    "path": "source/sha256_transform.v",
    "content": "/*\n*\n* Copyright (c) 2011 fpgaminer@bitcoin-mining.com\n*\n*\n*\n* This program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU General Public License as published by\n* the Free Software Foundation, either version 3 of the License, or\n* (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n* GNU General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License\n* along with this program.  If not, see <http://www.gnu.org/licenses/>.\n* \n*/\n\n\n`timescale 1ns/1ps\n\n// A quick define to help index 32-bit words inside a larger register.\n`define IDX(x) (((x)+1)*(32)-1):((x)*(32))\n\n// Perform a SHA-256 transformation on the given 512-bit data, and 256-bit\n// initial state,\n// Outputs one 256-bit hash every LOOP cycle(s).\n//\n// The LOOP parameter determines both the size and speed of this module.\n// A value of 1 implies a fully unrolled SHA-256 calculation spanning 64 round\n// modules and calculating a full SHA-256 hash every clock cycle. A value of\n// 2 implies a half-unrolled loop, with 32 round modules and calculating\n// a full hash in 2 clock cycles. And so forth.\n\nmodule sha256_transform #(\n\tparameter LOOP = 7'd64\t\t// For ltcminer\n) (\n\tinput clk,\n\tinput feedback,\n\tinput [5:0] cnt,\n\tinput [255:0] rx_state,\n\tinput [511:0] rx_input,\n\toutput reg [255:0] tx_hash\n);\n\n\t// Constants defined by the SHA-2 standard.\n\tlocalparam Ks = {\n\t\t32'h428a2f98, 32'h71374491, 32'hb5c0fbcf, 32'he9b5dba5,\n\t\t32'h3956c25b, 32'h59f111f1, 32'h923f82a4, 32'hab1c5ed5,\n\t\t32'hd807aa98, 32'h12835b01, 32'h243185be, 32'h550c7dc3,\n\t\t32'h72be5d74, 32'h80deb1fe, 32'h9bdc06a7, 32'hc19bf174,\n\t\t32'he49b69c1, 32'hefbe4786, 32'h0fc19dc6, 32'h240ca1cc,\n\t\t32'h2de92c6f, 32'h4a7484aa, 32'h5cb0a9dc, 32'h76f988da,\n\t\t32'h983e5152, 32'ha831c66d, 32'hb00327c8, 32'hbf597fc7,\n\t\t32'hc6e00bf3, 32'hd5a79147, 32'h06ca6351, 32'h14292967,\n\t\t32'h27b70a85, 32'h2e1b2138, 32'h4d2c6dfc, 32'h53380d13,\n\t\t32'h650a7354, 32'h766a0abb, 32'h81c2c92e, 32'h92722c85,\n\t\t32'ha2bfe8a1, 32'ha81a664b, 32'hc24b8b70, 32'hc76c51a3,\n\t\t32'hd192e819, 32'hd6990624, 32'hf40e3585, 32'h106aa070,\n\t\t32'h19a4c116, 32'h1e376c08, 32'h2748774c, 32'h34b0bcb5,\n\t\t32'h391c0cb3, 32'h4ed8aa4a, 32'h5b9cca4f, 32'h682e6ff3,\n\t\t32'h748f82ee, 32'h78a5636f, 32'h84c87814, 32'h8cc70208,\n\t\t32'h90befffa, 32'ha4506ceb, 32'hbef9a3f7, 32'hc67178f2};\n\n\n\tgenvar i;\n\n\tgenerate\n\n\t\tfor (i = 0; i < 64/LOOP; i = i + 1) begin : HASHERS\n\t\t\t// These are declared as registers in sha256_digester\n\t\t\twire [511:0] W;\t\t\t// reg tx_w\n\t\t\twire [255:0] state;\t\t// reg tx_state\n\n\t\t\tif(i == 0)\n\t\t\t\tsha256_digester U (\n\t\t\t\t\t.clk(clk),\n\t\t\t\t\t.k(Ks[32*(63-cnt) +: 32]),\n\t\t\t\t\t.rx_w(feedback ? W : rx_input),\n\t\t\t\t\t.rx_state(feedback ? state : rx_state),\n\t\t\t\t\t.tx_w(W),\n\t\t\t\t\t.tx_state(state)\n\t\t\t\t);\n\t\t\telse\n\t\t\t\tsha256_digester U (\n\t\t\t\t\t.clk(clk),\n\t\t\t\t\t.k(Ks[32*(63-LOOP*i-cnt) +: 32]),\n\t\t\t\t\t.rx_w(feedback ? W : HASHERS[i-1].W),\n\t\t\t\t\t.rx_state(feedback ? state : HASHERS[i-1].state),\n\t\t\t\t\t.tx_w(W),\n\t\t\t\t\t.tx_state(state)\n\t\t\t\t);\n\t\tend\n\n\tendgenerate\n\n\talways @ (posedge clk)\n\tbegin\n\t\tif (!feedback)\n\t\tbegin\n\t\t\ttx_hash[`IDX(0)] <= rx_state[`IDX(0)] + HASHERS[64/LOOP-6'd1].state[`IDX(0)];\n\t\t\ttx_hash[`IDX(1)] <= rx_state[`IDX(1)] + HASHERS[64/LOOP-6'd1].state[`IDX(1)];\n\t\t\ttx_hash[`IDX(2)] <= rx_state[`IDX(2)] + HASHERS[64/LOOP-6'd1].state[`IDX(2)];\n\t\t\ttx_hash[`IDX(3)] <= rx_state[`IDX(3)] + HASHERS[64/LOOP-6'd1].state[`IDX(3)];\n\t\t\ttx_hash[`IDX(4)] <= rx_state[`IDX(4)] + HASHERS[64/LOOP-6'd1].state[`IDX(4)];\n\t\t\ttx_hash[`IDX(5)] <= rx_state[`IDX(5)] + HASHERS[64/LOOP-6'd1].state[`IDX(5)];\n\t\t\ttx_hash[`IDX(6)] <= rx_state[`IDX(6)] + HASHERS[64/LOOP-6'd1].state[`IDX(6)];\n\t\t\ttx_hash[`IDX(7)] <= rx_state[`IDX(7)] + HASHERS[64/LOOP-6'd1].state[`IDX(7)];\n\t\tend\n\tend\n\n\nendmodule\n\n\nmodule sha256_digester (clk, k, rx_w, rx_state, tx_w, tx_state);\n\n\tinput clk;\n\tinput [31:0] k;\n\tinput [511:0] rx_w;\n\tinput [255:0] rx_state;\n\n\toutput reg [511:0] tx_w;\n\toutput reg [255:0] tx_state;\n\n\n\twire [31:0] e0_w, e1_w, ch_w, maj_w, s0_w, s1_w;\n\n\n\te0\te0_blk\t(rx_state[`IDX(0)], e0_w);\n\te1\te1_blk\t(rx_state[`IDX(4)], e1_w);\n\tch\tch_blk\t(rx_state[`IDX(4)], rx_state[`IDX(5)], rx_state[`IDX(6)], ch_w);\n\tmaj\tmaj_blk\t(rx_state[`IDX(0)], rx_state[`IDX(1)], rx_state[`IDX(2)], maj_w);\n\ts0\ts0_blk\t(rx_w[63:32], s0_w);\n\ts1\ts1_blk\t(rx_w[479:448], s1_w);\n\n\twire [31:0] t1 = rx_state[`IDX(7)] + e1_w + ch_w + rx_w[31:0] + k;\n\twire [31:0] t2 = e0_w + maj_w;\n\twire [31:0] new_w = s1_w + rx_w[319:288] + s0_w + rx_w[31:0];\n\t\n\n\talways @ (posedge clk)\n\tbegin\n\t\ttx_w[511:480] <= new_w;\n\t\ttx_w[479:0] <= rx_w[511:32];\n\n\t\ttx_state[`IDX(7)] <= rx_state[`IDX(6)];\n\t\ttx_state[`IDX(6)] <= rx_state[`IDX(5)];\n\t\ttx_state[`IDX(5)] <= rx_state[`IDX(4)];\n\t\ttx_state[`IDX(4)] <= rx_state[`IDX(3)] + t1;\n\t\ttx_state[`IDX(3)] <= rx_state[`IDX(2)];\n\t\ttx_state[`IDX(2)] <= rx_state[`IDX(1)];\n\t\ttx_state[`IDX(1)] <= rx_state[`IDX(0)];\n\t\ttx_state[`IDX(0)] <= t1 + t2;\n\tend\n\nendmodule\n"
  },
  {
    "path": "source/test_ltcminer.v",
    "content": "// Testbench for ltcminer.v\n\n`timescale 1ns/1ps\n\nmodule test_ltcminer ();\n\n\treg clk = 1'b0;\n\t\n\t wire [7:0] LEDS_out;\n\tltcminer uut (clk, LEDS_out);\n\t//ltcminer uut (clk);\n\n\treg [31:0] cycle = 32'd0;\n\n\tinitial begin\n\t\tclk = 0;\n\t\t\n\t\twhile(1)\n\t\tbegin\n\t\t\t#5 clk = 1; #5 clk = 0;\n\t\tend\n\tend\n\n\talways @ (posedge clk)\n\tbegin\n\t\tcycle <= cycle + 32'd1;\n\tend\n\nendmodule\n\n"
  }
]