diff --git a/docs/finn/example_networks.rst b/docs/finn/example_networks.rst index e8b29a5fb862f6ebe917327a8f6c96edbf529b96..51089c591be08fbfc8032f91481e63715b55c657 100644 --- a/docs/finn/example_networks.rst +++ b/docs/finn/example_networks.rst @@ -15,22 +15,22 @@ The rows in the table are different steps of the FINN end-to-end flow. If a particular network is supported for a particular step in the current FINN version, this is indicated by an x mark in the table. -+-----------------------+------------+----------+----------+----------+----------+----------+ -| FINN step | Basic test | TFC-w1a1 | TFC-w1a2 | CNV-w1a1 | CNV-w1a2 | CNV-w2a2 | -+-----------------------+------------+----------+----------+----------+----------+----------+ -| Export/Import | x | x | x | x | | | -+-----------------------+------------+----------+----------+----------+----------+----------+ -| Streamlining | x | x | x | | | | -+-----------------------+------------+----------+----------+----------+----------+----------+ -| Convert to HLS layers | x | x | x | | | | -+-----------------------+------------+----------+----------+----------+----------+----------+ -| Stitched IP | x | x | x | | | | -+-----------------------+------------+----------+----------+----------+----------+----------+ -| Hardware test | x | x | x | | | | -+-----------------------+------------+----------+----------+----------+----------+----------+ -| npysim | x | x | x | | | | -+-----------------------+------------+----------+----------+----------+----------+----------+ -| rtlsim node-by-node | x | x | x | | | | -+-----------------------+------------+----------+----------+----------+----------+----------+ -| rtlsim stitched IP | x | x | x | | | | -+-----------------------+------------+----------+----------+----------+----------+----------+ ++-----------------------+------------+----------+----------+----------+----------+----------+----------+ +| FINN step | Basic test | TFC-w1a1 | TFC-w1a2 | TFC-w2a2 | CNV-w1a1 | CNV-w1a2 | CNV-w2a2 | ++-----------------------+------------+----------+----------+----------+----------+----------+----------+ +| Export/Import | x | x | x | x | x | | | ++-----------------------+------------+----------+----------+----------+----------+----------+----------+ +| Streamlining | x | x | x | x | | | | ++-----------------------+------------+----------+----------+----------+----------+----------+----------+ +| Convert to HLS layers | x | x | x | x | | | | ++-----------------------+------------+----------+----------+----------+----------+----------+----------+ +| Stitched IP | x | x | x | x | | | | ++-----------------------+------------+----------+----------+----------+----------+----------+----------+ +| Hardware test | x | x | x | | | | | ++-----------------------+------------+----------+----------+----------+----------+----------+----------+ +| npysim | x | x | x | x | | | | ++-----------------------+------------+----------+----------+----------+----------+----------+----------+ +| rtlsim node-by-node | x | x | x | x | | | | ++-----------------------+------------+----------+----------+----------+----------+----------+----------+ +| rtlsim stitched IP | x | x | x | x | | | | ++-----------------------+------------+----------+----------+----------+----------+----------+----------+ diff --git a/finn-rtllib/memstream/component.xml b/finn-rtllib/memstream/component.xml new file mode 100644 index 0000000000000000000000000000000000000000..6b728c0555a4889b8e76d5759233d1109a3002bd --- /dev/null +++ b/finn-rtllib/memstream/component.xml @@ -0,0 +1,1082 @@ +<?xml version="1.0" encoding="UTF-8"?> +<spirit:component xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <spirit:vendor>xilinx.com</spirit:vendor> + <spirit:library>user</spirit:library> + <spirit:name>memstream</spirit:name> + <spirit:version>1.0</spirit:version> + <spirit:busInterfaces> + <spirit:busInterface> + <spirit:name>m_axis_0</spirit:name> + <spirit:busType spirit:vendor="xilinx.com" spirit:library="interface" spirit:name="axis" spirit:version="1.0"/> + <spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="interface" spirit:name="axis_rtl" spirit:version="1.0"/> + <spirit:master/> + <spirit:portMaps> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TDATA</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_0_tdata</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TVALID</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_0_tvalid</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TREADY</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_0_tready</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + </spirit:portMaps> + </spirit:busInterface> + <spirit:busInterface> + <spirit:name>m_axis_1</spirit:name> + <spirit:busType spirit:vendor="xilinx.com" spirit:library="interface" spirit:name="axis" spirit:version="1.0"/> + <spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="interface" spirit:name="axis_rtl" spirit:version="1.0"/> + <spirit:master/> + <spirit:portMaps> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TDATA</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_1_tdata</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TVALID</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_1_tvalid</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TREADY</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_1_tready</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + </spirit:portMaps> + </spirit:busInterface> + <spirit:busInterface> + <spirit:name>m_axis_2</spirit:name> + <spirit:busType spirit:vendor="xilinx.com" spirit:library="interface" spirit:name="axis" spirit:version="1.0"/> + <spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="interface" spirit:name="axis_rtl" spirit:version="1.0"/> + <spirit:master/> + <spirit:portMaps> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TDATA</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_2_tdata</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TVALID</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_2_tvalid</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TREADY</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_2_tready</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + </spirit:portMaps> + </spirit:busInterface> + <spirit:busInterface> + <spirit:name>m_axis_3</spirit:name> + <spirit:busType spirit:vendor="xilinx.com" spirit:library="interface" spirit:name="axis" spirit:version="1.0"/> + <spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="interface" spirit:name="axis_rtl" spirit:version="1.0"/> + <spirit:master/> + <spirit:portMaps> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TDATA</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_3_tdata</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TVALID</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_3_tvalid</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TREADY</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_3_tready</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + </spirit:portMaps> + </spirit:busInterface> + <spirit:busInterface> + <spirit:name>m_axis_4</spirit:name> + <spirit:busType spirit:vendor="xilinx.com" spirit:library="interface" spirit:name="axis" spirit:version="1.0"/> + <spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="interface" spirit:name="axis_rtl" spirit:version="1.0"/> + <spirit:master/> + <spirit:portMaps> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TDATA</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_4_tdata</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TVALID</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_4_tvalid</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TREADY</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_4_tready</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + </spirit:portMaps> + </spirit:busInterface> + <spirit:busInterface> + <spirit:name>m_axis_5</spirit:name> + <spirit:busType spirit:vendor="xilinx.com" spirit:library="interface" spirit:name="axis" spirit:version="1.0"/> + <spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="interface" spirit:name="axis_rtl" spirit:version="1.0"/> + <spirit:master/> + <spirit:portMaps> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TDATA</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_5_tdata</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TVALID</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_5_tvalid</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>TREADY</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>m_axis_5_tready</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + </spirit:portMaps> + </spirit:busInterface> + <spirit:busInterface> + <spirit:name>aresetn</spirit:name> + <spirit:busType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset" spirit:version="1.0"/> + <spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="reset_rtl" spirit:version="1.0"/> + <spirit:slave/> + <spirit:portMaps> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>RST</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>aresetn</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + </spirit:portMaps> + <spirit:parameters> + <spirit:parameter> + <spirit:name>POLARITY</spirit:name> + <spirit:value spirit:id="BUSIFPARAM_VALUE.ARESETN.POLARITY" spirit:choiceRef="choice_list_9d8b0d81">ACTIVE_LOW</spirit:value> + </spirit:parameter> + </spirit:parameters> + </spirit:busInterface> + <spirit:busInterface> + <spirit:name>aclk</spirit:name> + <spirit:busType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="clock" spirit:version="1.0"/> + <spirit:abstractionType spirit:vendor="xilinx.com" spirit:library="signal" spirit:name="clock_rtl" spirit:version="1.0"/> + <spirit:slave/> + <spirit:portMaps> + <spirit:portMap> + <spirit:logicalPort> + <spirit:name>CLK</spirit:name> + </spirit:logicalPort> + <spirit:physicalPort> + <spirit:name>aclk</spirit:name> + </spirit:physicalPort> + </spirit:portMap> + </spirit:portMaps> + <spirit:parameters> + <spirit:parameter> + <spirit:name>ASSOCIATED_BUSIF</spirit:name> + <spirit:value spirit:id="BUSIFPARAM_VALUE.ACLK.ASSOCIATED_BUSIF">m_axis_0:m_axis_1:m_axis_2:m_axis_3:m_axis_4:m_axis_5</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>ASSOCIATED_RESET</spirit:name> + <spirit:value spirit:id="BUSIFPARAM_VALUE.ACLK.ASSOCIATED_RESET">aresetn</spirit:value> + </spirit:parameter> + </spirit:parameters> + </spirit:busInterface> + </spirit:busInterfaces> + <spirit:model> + <spirit:views> + <spirit:view> + <spirit:name>xilinx_anylanguagesynthesis</spirit:name> + <spirit:displayName>Synthesis</spirit:displayName> + <spirit:envIdentifier>:vivado.xilinx.com:synthesis</spirit:envIdentifier> + <spirit:language>Verilog</spirit:language> + <spirit:modelName>memstream</spirit:modelName> + <spirit:fileSetRef> + <spirit:localName>xilinx_anylanguagesynthesis_view_fileset</spirit:localName> + </spirit:fileSetRef> + <spirit:parameters> + <spirit:parameter> + <spirit:name>viewChecksum</spirit:name> + <spirit:value>ba6d3300</spirit:value> + </spirit:parameter> + </spirit:parameters> + </spirit:view> + <spirit:view> + <spirit:name>xilinx_anylanguagebehavioralsimulation</spirit:name> + <spirit:displayName>Simulation</spirit:displayName> + <spirit:envIdentifier>:vivado.xilinx.com:simulation</spirit:envIdentifier> + <spirit:language>Verilog</spirit:language> + <spirit:modelName>memstream</spirit:modelName> + <spirit:fileSetRef> + <spirit:localName>xilinx_anylanguagebehavioralsimulation_view_fileset</spirit:localName> + </spirit:fileSetRef> + <spirit:parameters> + <spirit:parameter> + <spirit:name>viewChecksum</spirit:name> + <spirit:value>54f61a0e</spirit:value> + </spirit:parameter> + </spirit:parameters> + </spirit:view> + <spirit:view> + <spirit:name>xilinx_xpgui</spirit:name> + <spirit:displayName>UI Layout</spirit:displayName> + <spirit:envIdentifier>:vivado.xilinx.com:xgui.ui</spirit:envIdentifier> + <spirit:fileSetRef> + <spirit:localName>xilinx_xpgui_view_fileset</spirit:localName> + </spirit:fileSetRef> + <spirit:parameters> + <spirit:parameter> + <spirit:name>viewChecksum</spirit:name> + <spirit:value>92c3ebfc</spirit:value> + </spirit:parameter> + </spirit:parameters> + </spirit:view> + </spirit:views> + <spirit:ports> + <spirit:port> + <spirit:name>aclk</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>aresetn</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>config_address</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:vector> + <spirit:left spirit:format="long">31</spirit:left> + <spirit:right spirit:format="long">0</spirit:right> + </spirit:vector> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic_vector</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>config_ce</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>config_we</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>config_d0</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:vector> + <spirit:left spirit:format="long">31</spirit:left> + <spirit:right spirit:format="long">0</spirit:right> + </spirit:vector> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic_vector</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>config_q0</spirit:name> + <spirit:wire> + <spirit:direction>out</spirit:direction> + <spirit:vector> + <spirit:left spirit:format="long">31</spirit:left> + <spirit:right spirit:format="long">0</spirit:right> + </spirit:vector> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic_vector</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_0_afull</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_0_tready</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + <spirit:driver> + <spirit:defaultValue spirit:format="long">1</spirit:defaultValue> + </spirit:driver> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_0_tvalid</spirit:name> + <spirit:wire> + <spirit:direction>out</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_0_tdata</spirit:name> + <spirit:wire> + <spirit:direction>out</spirit:direction> + <spirit:vector> + <spirit:left spirit:format="long" spirit:resolve="dependent" spirit:dependency="(spirit:decode(id('MODELPARAM_VALUE.STRM0_WIDTH')) - 1)">31</spirit:left> + <spirit:right spirit:format="long">0</spirit:right> + </spirit:vector> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic_vector</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_1_afull</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_1_tready</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + <spirit:driver> + <spirit:defaultValue spirit:format="long">1</spirit:defaultValue> + </spirit:driver> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_1_tvalid</spirit:name> + <spirit:wire> + <spirit:direction>out</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_1_tdata</spirit:name> + <spirit:wire> + <spirit:direction>out</spirit:direction> + <spirit:vector> + <spirit:left spirit:format="long" spirit:resolve="dependent" spirit:dependency="(spirit:decode(id('MODELPARAM_VALUE.STRM1_WIDTH')) - 1)">31</spirit:left> + <spirit:right spirit:format="long">0</spirit:right> + </spirit:vector> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic_vector</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_2_afull</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_2_tready</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + <spirit:driver> + <spirit:defaultValue spirit:format="long">1</spirit:defaultValue> + </spirit:driver> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_2_tvalid</spirit:name> + <spirit:wire> + <spirit:direction>out</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_2_tdata</spirit:name> + <spirit:wire> + <spirit:direction>out</spirit:direction> + <spirit:vector> + <spirit:left spirit:format="long" spirit:resolve="dependent" spirit:dependency="(spirit:decode(id('MODELPARAM_VALUE.STRM2_WIDTH')) - 1)">31</spirit:left> + <spirit:right spirit:format="long">0</spirit:right> + </spirit:vector> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic_vector</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_3_afull</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_3_tready</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + <spirit:driver> + <spirit:defaultValue spirit:format="long">1</spirit:defaultValue> + </spirit:driver> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_3_tvalid</spirit:name> + <spirit:wire> + <spirit:direction>out</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_3_tdata</spirit:name> + <spirit:wire> + <spirit:direction>out</spirit:direction> + <spirit:vector> + <spirit:left spirit:format="long" spirit:resolve="dependent" spirit:dependency="(spirit:decode(id('MODELPARAM_VALUE.STRM3_WIDTH')) - 1)">31</spirit:left> + <spirit:right spirit:format="long">0</spirit:right> + </spirit:vector> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic_vector</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_4_afull</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_4_tready</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + <spirit:driver> + <spirit:defaultValue spirit:format="long">1</spirit:defaultValue> + </spirit:driver> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_4_tvalid</spirit:name> + <spirit:wire> + <spirit:direction>out</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_4_tdata</spirit:name> + <spirit:wire> + <spirit:direction>out</spirit:direction> + <spirit:vector> + <spirit:left spirit:format="long" spirit:resolve="dependent" spirit:dependency="(spirit:decode(id('MODELPARAM_VALUE.STRM4_WIDTH')) - 1)">31</spirit:left> + <spirit:right spirit:format="long">0</spirit:right> + </spirit:vector> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic_vector</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_5_afull</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_5_tready</spirit:name> + <spirit:wire> + <spirit:direction>in</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + <spirit:driver> + <spirit:defaultValue spirit:format="long">1</spirit:defaultValue> + </spirit:driver> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_5_tvalid</spirit:name> + <spirit:wire> + <spirit:direction>out</spirit:direction> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + <spirit:port> + <spirit:name>m_axis_5_tdata</spirit:name> + <spirit:wire> + <spirit:direction>out</spirit:direction> + <spirit:vector> + <spirit:left spirit:format="long" spirit:resolve="dependent" spirit:dependency="(spirit:decode(id('MODELPARAM_VALUE.STRM5_WIDTH')) - 1)">31</spirit:left> + <spirit:right spirit:format="long">0</spirit:right> + </spirit:vector> + <spirit:wireTypeDefs> + <spirit:wireTypeDef> + <spirit:typeName>std_logic_vector</spirit:typeName> + <spirit:viewNameRef>xilinx_anylanguagesynthesis</spirit:viewNameRef> + <spirit:viewNameRef>xilinx_anylanguagebehavioralsimulation</spirit:viewNameRef> + </spirit:wireTypeDef> + </spirit:wireTypeDefs> + </spirit:wire> + </spirit:port> + </spirit:ports> + <spirit:modelParameters> + <spirit:modelParameter xsi:type="spirit:nameValueTypeType" spirit:dataType="integer"> + <spirit:name>CONFIG_EN</spirit:name> + <spirit:displayName>Config En</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.CONFIG_EN">1</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>NSTREAMS</spirit:name> + <spirit:displayName>Nstreams</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.NSTREAMS">6</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>MEM_DEPTH</spirit:name> + <spirit:displayName>Mem Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.MEM_DEPTH">13824</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>MEM_WIDTH</spirit:name> + <spirit:displayName>Mem Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.MEM_WIDTH">32</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="string"> + <spirit:name>MEM_INIT</spirit:name> + <spirit:displayName>Mem Init</spirit:displayName> + <spirit:value spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.MEM_INIT">./</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM0_WIDTH</spirit:name> + <spirit:displayName>Strm0 Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM0_WIDTH">32</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM1_WIDTH</spirit:name> + <spirit:displayName>Strm1 Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM1_WIDTH">32</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM2_WIDTH</spirit:name> + <spirit:displayName>Strm2 Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM2_WIDTH">32</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM3_WIDTH</spirit:name> + <spirit:displayName>Strm3 Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM3_WIDTH">32</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM4_WIDTH</spirit:name> + <spirit:displayName>Strm4 Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM4_WIDTH">32</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM5_WIDTH</spirit:name> + <spirit:displayName>Strm5 Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM5_WIDTH">32</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM0_DEPTH</spirit:name> + <spirit:displayName>Strm0 Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM0_DEPTH">2304</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM1_DEPTH</spirit:name> + <spirit:displayName>Strm1 Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM1_DEPTH">2304</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM2_DEPTH</spirit:name> + <spirit:displayName>Strm2 Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM2_DEPTH">2304</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM3_DEPTH</spirit:name> + <spirit:displayName>Strm3 Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM3_DEPTH">2304</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM4_DEPTH</spirit:name> + <spirit:displayName>Strm4 Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM4_DEPTH">2304</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM5_DEPTH</spirit:name> + <spirit:displayName>Strm5 Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM5_DEPTH">2304</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM0_OFFSET</spirit:name> + <spirit:displayName>Strm0 Offset</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM0_OFFSET">0</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM1_OFFSET</spirit:name> + <spirit:displayName>Strm1 Offset</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM1_OFFSET">2304</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM2_OFFSET</spirit:name> + <spirit:displayName>Strm2 Offset</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM2_OFFSET">4608</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM3_OFFSET</spirit:name> + <spirit:displayName>Strm3 Offset</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM3_OFFSET">6912</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM4_OFFSET</spirit:name> + <spirit:displayName>Strm4 Offset</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM4_OFFSET">9216</spirit:value> + </spirit:modelParameter> + <spirit:modelParameter spirit:dataType="integer"> + <spirit:name>STRM5_OFFSET</spirit:name> + <spirit:displayName>Strm5 Offset</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="generated" spirit:id="MODELPARAM_VALUE.STRM5_OFFSET">11520</spirit:value> + </spirit:modelParameter> + </spirit:modelParameters> + </spirit:model> + <spirit:choices> + <spirit:choice> + <spirit:name>choice_list_9d8b0d81</spirit:name> + <spirit:enumeration>ACTIVE_HIGH</spirit:enumeration> + <spirit:enumeration>ACTIVE_LOW</spirit:enumeration> + </spirit:choice> + </spirit:choices> + <spirit:fileSets> + <spirit:fileSet> + <spirit:name>xilinx_anylanguagesynthesis_view_fileset</spirit:name> + <spirit:file> + <spirit:name>hdl/memstream.v</spirit:name> + <spirit:fileType>verilogSource</spirit:fileType> + </spirit:file> + <spirit:file> + <spirit:name>hdl/mux.v</spirit:name> + <spirit:fileType>verilogSource</spirit:fileType> + </spirit:file> + <spirit:file> + <spirit:name>hdl/ramb18.v</spirit:name> + <spirit:fileType>verilogSource</spirit:fileType> + <spirit:userFileType>CHECKSUM_13578c44</spirit:userFileType> + </spirit:file> + </spirit:fileSet> + <spirit:fileSet> + <spirit:name>xilinx_anylanguagebehavioralsimulation_view_fileset</spirit:name> + <spirit:file> + <spirit:name>sim/tb_memstream.v</spirit:name> + <spirit:fileType>verilogSource</spirit:fileType> + </spirit:file> + </spirit:fileSet> + <spirit:fileSet> + <spirit:name>xilinx_xpgui_view_fileset</spirit:name> + <spirit:file> + <spirit:name>xgui/memstream_v1_0.tcl</spirit:name> + <spirit:fileType>tclSource</spirit:fileType> + <spirit:userFileType>CHECKSUM_92c3ebfc</spirit:userFileType> + <spirit:userFileType>XGUI_VERSION_2</spirit:userFileType> + </spirit:file> + </spirit:fileSet> + </spirit:fileSets> + <spirit:description>memstream_v1_0</spirit:description> + <spirit:parameters> + <spirit:parameter> + <spirit:name>CONFIG_EN</spirit:name> + <spirit:displayName>Config En</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.CONFIG_EN">1</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>NSTREAMS</spirit:name> + <spirit:displayName>Nstreams</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.NSTREAMS">6</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>MEM_DEPTH</spirit:name> + <spirit:displayName>Mem Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.MEM_DEPTH">13824</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>MEM_WIDTH</spirit:name> + <spirit:displayName>Mem Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.MEM_WIDTH">32</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>MEM_INIT</spirit:name> + <spirit:displayName>Mem Init</spirit:displayName> + <spirit:value spirit:resolve="user" spirit:id="PARAM_VALUE.MEM_INIT">./</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM0_WIDTH</spirit:name> + <spirit:displayName>Strm0 Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM0_WIDTH">32</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM1_WIDTH</spirit:name> + <spirit:displayName>Strm1 Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM1_WIDTH">32</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM2_WIDTH</spirit:name> + <spirit:displayName>Strm2 Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM2_WIDTH">32</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM3_WIDTH</spirit:name> + <spirit:displayName>Strm3 Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM3_WIDTH">32</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM4_WIDTH</spirit:name> + <spirit:displayName>Strm4 Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM4_WIDTH">32</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM5_WIDTH</spirit:name> + <spirit:displayName>Strm5 Width</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM5_WIDTH">32</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM0_DEPTH</spirit:name> + <spirit:displayName>Strm0 Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM0_DEPTH">2304</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM1_DEPTH</spirit:name> + <spirit:displayName>Strm1 Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM1_DEPTH">2304</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM2_DEPTH</spirit:name> + <spirit:displayName>Strm2 Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM2_DEPTH">2304</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM3_DEPTH</spirit:name> + <spirit:displayName>Strm3 Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM3_DEPTH">2304</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM4_DEPTH</spirit:name> + <spirit:displayName>Strm4 Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM4_DEPTH">2304</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM5_DEPTH</spirit:name> + <spirit:displayName>Strm5 Depth</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM5_DEPTH">2304</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM0_OFFSET</spirit:name> + <spirit:displayName>Strm0 Offset</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM0_OFFSET">0</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM1_OFFSET</spirit:name> + <spirit:displayName>Strm1 Offset</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM1_OFFSET">2304</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM2_OFFSET</spirit:name> + <spirit:displayName>Strm2 Offset</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM2_OFFSET">4608</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM3_OFFSET</spirit:name> + <spirit:displayName>Strm3 Offset</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM3_OFFSET">6912</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM4_OFFSET</spirit:name> + <spirit:displayName>Strm4 Offset</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM4_OFFSET">9216</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>STRM5_OFFSET</spirit:name> + <spirit:displayName>Strm5 Offset</spirit:displayName> + <spirit:value spirit:format="long" spirit:resolve="user" spirit:id="PARAM_VALUE.STRM5_OFFSET">11520</spirit:value> + </spirit:parameter> + <spirit:parameter> + <spirit:name>Component_Name</spirit:name> + <spirit:value spirit:resolve="user" spirit:id="PARAM_VALUE.Component_Name" spirit:order="1">memstream_v1_0</spirit:value> + </spirit:parameter> + </spirit:parameters> + <spirit:vendorExtensions> + <xilinx:coreExtensions> + <xilinx:supportedFamilies> + <xilinx:family xilinx:lifeCycle="Production">zynq</xilinx:family> + <xilinx:family xilinx:lifeCycle="Beta">artix7</xilinx:family> + <xilinx:family xilinx:lifeCycle="Beta">artix7l</xilinx:family> + <xilinx:family xilinx:lifeCycle="Beta">kintex7</xilinx:family> + <xilinx:family xilinx:lifeCycle="Beta">kintex7l</xilinx:family> + <xilinx:family xilinx:lifeCycle="Beta">kintexu</xilinx:family> + <xilinx:family xilinx:lifeCycle="Beta">kintexuplus</xilinx:family> + <xilinx:family xilinx:lifeCycle="Beta">spartan7</xilinx:family> + <xilinx:family xilinx:lifeCycle="Beta">aartix7</xilinx:family> + <xilinx:family xilinx:lifeCycle="Beta">aspartan7</xilinx:family> + <xilinx:family xilinx:lifeCycle="Beta">azynq</xilinx:family> + <xilinx:family xilinx:lifeCycle="Beta">zynquplus</xilinx:family> + <xilinx:family xilinx:lifeCycle="Production">virtexuplus</xilinx:family> + </xilinx:supportedFamilies> + <xilinx:taxonomies> + <xilinx:taxonomy>/UserIP</xilinx:taxonomy> + </xilinx:taxonomies> + <xilinx:displayName>memstream_v1_0</xilinx:displayName> + <xilinx:definitionSource>package_project</xilinx:definitionSource> + <xilinx:coreRevision>2</xilinx:coreRevision> + <xilinx:coreCreationDateTime>2019-11-04T19:37:20Z</xilinx:coreCreationDateTime> + <xilinx:tags> + <xilinx:tag xilinx:name="nopcore"/> + <xilinx:tag xilinx:name="ui.data.coregen.dd@7a3d79be_ARCHIVE_LOCATION">c:/Users/lucianp/Documents/git/finn-rtllib/memstream</xilinx:tag> + <xilinx:tag xilinx:name="ui.data.coregen.dd@6ca546af_ARCHIVE_LOCATION">c:/Users/lucianp/Documents/git/finn-rtllib/memstream</xilinx:tag> + <xilinx:tag xilinx:name="ui.data.coregen.dd@2bb0c52f_ARCHIVE_LOCATION">c:/Users/lucianp/Documents/git/finn-rtllib/memstream</xilinx:tag> + <xilinx:tag xilinx:name="ui.data.coregen.dd@1f6f8fe4_ARCHIVE_LOCATION">c:/Users/lucianp/Documents/git/finn-rtllib/memstream</xilinx:tag> + <xilinx:tag xilinx:name="ui.data.coregen.dd@79ecbc44_ARCHIVE_LOCATION">c:/Users/lucianp/Documents/git/finn-rtllib/memstream</xilinx:tag> + <xilinx:tag xilinx:name="ui.data.coregen.dd@22fd683_ARCHIVE_LOCATION">c:/Users/lucianp/Documents/git/finn-rtllib/memstream</xilinx:tag> + <xilinx:tag xilinx:name="ui.data.coregen.dd@2c00346d_ARCHIVE_LOCATION">c:/Users/lucianp/Documents/git/finn-rtllib/memstream</xilinx:tag> + </xilinx:tags> + </xilinx:coreExtensions> + <xilinx:packagingInfo> + <xilinx:xilinxVersion>2019.1.3</xilinx:xilinxVersion> + <xilinx:checksum xilinx:scope="busInterfaces" xilinx:value="6d8b2551"/> + <xilinx:checksum xilinx:scope="fileGroups" xilinx:value="5e0c4694"/> + <xilinx:checksum xilinx:scope="ports" xilinx:value="cabd7433"/> + <xilinx:checksum xilinx:scope="hdlParameters" xilinx:value="f63127c8"/> + <xilinx:checksum xilinx:scope="parameters" xilinx:value="5365a08b"/> + </xilinx:packagingInfo> + </spirit:vendorExtensions> +</spirit:component> diff --git a/finn-rtllib/memstream/hdl/memstream.v b/finn-rtllib/memstream/hdl/memstream.v new file mode 100644 index 0000000000000000000000000000000000000000..a1c8e066d7290699575c94b0ac939d5a3fb27b19 --- /dev/null +++ b/finn-rtllib/memstream/hdl/memstream.v @@ -0,0 +1,465 @@ +/* + Copyright (c) 2020, Xilinx + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of FINN nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +module memstream +#( +//parameters to enable/disable axi-mm, set number of streams, set readmemh for memory, set per-stream offsets in memory, set per-stream widths + parameter CONFIG_EN = 1, + parameter NSTREAMS = 6,//1 up to 6 + + parameter MEM_DEPTH = 13824, + parameter MEM_WIDTH = 32, + parameter MEM_INIT = "./", + + //widths per stream + parameter STRM0_WIDTH = 32, + parameter STRM1_WIDTH = 32, + parameter STRM2_WIDTH = 32, + parameter STRM3_WIDTH = 32, + parameter STRM4_WIDTH = 32, + parameter STRM5_WIDTH = 32, + + //depths per stream + parameter STRM0_DEPTH = 2304, + parameter STRM1_DEPTH = 2304, + parameter STRM2_DEPTH = 2304, + parameter STRM3_DEPTH = 2304, + parameter STRM4_DEPTH = 2304, + parameter STRM5_DEPTH = 2304, + + //offsets for each stream + parameter STRM0_OFFSET = 0, + parameter STRM1_OFFSET = 2304, + parameter STRM2_OFFSET = 4608, + parameter STRM3_OFFSET = 6912, + parameter STRM4_OFFSET = 9216, + parameter STRM5_OFFSET = 11520 +) + +( + input aclk, + input aresetn, + + //optional configuration interface compatible with ap_memory + input [31:0] config_address, + input config_ce, + input config_we, + input [31:0] config_d0, + output [31:0] config_q0, + + //multiple output AXI Streams, TDATA width rounded to multiple of 8 bits + input m_axis_0_afull, + input m_axis_0_tready, + output m_axis_0_tvalid, + output [((STRM0_WIDTH+7)/8)*8-1:0] m_axis_0_tdata, + + input m_axis_1_afull, + input m_axis_1_tready, + output m_axis_1_tvalid, + output [((STRM1_WIDTH+7)/8)*8-1:0] m_axis_1_tdata, + + input m_axis_2_afull, + input m_axis_2_tready, + output m_axis_2_tvalid, + output [((STRM2_WIDTH+7)/8)*8-1:0] m_axis_2_tdata, + + input m_axis_3_afull, + input m_axis_3_tready, + output m_axis_3_tvalid, + output [((STRM3_WIDTH+7)/8)*8-1:0] m_axis_3_tdata, + + input m_axis_4_afull, + input m_axis_4_tready, + output m_axis_4_tvalid, + output [((STRM4_WIDTH+7)/8)*8-1:0] m_axis_4_tdata, + + input m_axis_5_afull, + input m_axis_5_tready, + output m_axis_5_tvalid, + output [((STRM5_WIDTH+7)/8)*8-1:0] m_axis_5_tdata + + +); + +//calculate number of RAMB18 blocks we need depth-wise +localparam NMEMBLOCKS = (MEM_DEPTH+1023) / 1024; //ceil(MEM_DEPTH/1024) + +//calculate width of address for each block +localparam BLOCKADRWIDTH = NMEMBLOCKS > 1 ? 10 : $clog2(MEM_DEPTH); + +//determine whether a stream needs to multiplex between memory blocks +localparam STRM0_MUX = ((STRM0_OFFSET/1024) != ((STRM0_OFFSET+STRM0_DEPTH)/1024)); +localparam STRM1_MUX = ((STRM1_OFFSET/1024) != ((STRM1_OFFSET+STRM1_DEPTH)/1024)); +localparam STRM2_MUX = ((STRM2_OFFSET/1024) != ((STRM2_OFFSET+STRM2_DEPTH)/1024)); +localparam STRM3_MUX = ((STRM3_OFFSET/1024) != ((STRM3_OFFSET+STRM3_DEPTH)/1024)); +localparam STRM4_MUX = ((STRM4_OFFSET/1024) != ((STRM4_OFFSET+STRM4_DEPTH)/1024)); +localparam STRM5_MUX = ((STRM5_OFFSET/1024) != ((STRM5_OFFSET+STRM5_DEPTH)/1024)); + +//determine what the base block of each stream is +localparam STRM0_BLOCK = (STRM0_OFFSET/1024); +localparam STRM1_BLOCK = (STRM1_OFFSET/1024); +localparam STRM2_BLOCK = (STRM2_OFFSET/1024); +localparam STRM3_BLOCK = (STRM3_OFFSET/1024); +localparam STRM4_BLOCK = (STRM4_OFFSET/1024); +localparam STRM5_BLOCK = (STRM5_OFFSET/1024); + +//determine what the end block of each stream is +localparam STRM0_END_BLOCK = ((STRM0_OFFSET+STRM0_DEPTH-1)/1024); +localparam STRM1_END_BLOCK = ((STRM1_OFFSET+STRM1_DEPTH-1)/1024); +localparam STRM2_END_BLOCK = ((STRM2_OFFSET+STRM2_DEPTH-1)/1024); +localparam STRM3_END_BLOCK = ((STRM3_OFFSET+STRM3_DEPTH-1)/1024); +localparam STRM4_END_BLOCK = ((STRM4_OFFSET+STRM4_DEPTH-1)/1024); +localparam STRM5_END_BLOCK = ((STRM5_OFFSET+STRM5_DEPTH-1)/1024); + +//determine the number of blocks spanned by each stream +localparam STRM0_NBLOCKS = STRM0_END_BLOCK - STRM0_BLOCK + 1; +localparam STRM1_NBLOCKS = STRM1_END_BLOCK - STRM1_BLOCK + 1; +localparam STRM2_NBLOCKS = STRM2_END_BLOCK - STRM2_BLOCK + 1; +localparam STRM3_NBLOCKS = STRM3_END_BLOCK - STRM3_BLOCK + 1; +localparam STRM4_NBLOCKS = STRM4_END_BLOCK - STRM4_BLOCK + 1; +localparam STRM5_NBLOCKS = STRM5_END_BLOCK - STRM5_BLOCK + 1; + +//TODO: check that memory width is equal to the widest stream +//TODO: check that the stream depths and offsets make sense, and that the memory depth is sufficient (or calculate depth here?) +initial begin + if((NSTREAMS < 1) | (NSTREAMS > 6)) begin + $display("Invalid setting for NSTREAMS, please set in range [1,6]"); + $finish(); + end +end + +//invert reset +wire rst; +assign rst = ~aresetn; + +//WARNING: pipeline depth is larger than the number of streams per port so we have in-flight writes that may see not-ready when they get executed +//solution: use prog-full to make sure we have an equal number of free slots in the stream to the read pipeline depth + +reg [$clog2(MEM_DEPTH)-1:0] strm0_addr = STRM0_OFFSET; +reg [$clog2(MEM_DEPTH)-1:0] strm1_addr = STRM1_OFFSET; +reg [$clog2(MEM_DEPTH)-1:0] strm2_addr = STRM2_OFFSET; +reg [$clog2(MEM_DEPTH)-1:0] strm3_addr = STRM3_OFFSET; +reg [$clog2(MEM_DEPTH)-1:0] strm4_addr = STRM4_OFFSET; +reg [$clog2(MEM_DEPTH)-1:0] strm5_addr = STRM5_OFFSET; + +reg strm0_incr_en; +reg strm1_incr_en; +reg strm2_incr_en; +reg strm3_incr_en; +reg strm4_incr_en; +reg strm5_incr_en; + +wire strm0_rst; +wire strm1_rst; +wire strm2_rst; +wire strm3_rst; +wire strm4_rst; +wire strm5_rst; + +reg strm0_ready; +reg strm1_ready; +reg strm2_ready; +reg strm3_ready; +reg strm4_ready; +reg strm5_ready; + +//arbiter: work on one stream at a time +//multiplex each port between (up to) half of the streams +reg [1:0] current_stream_porta = 0; +reg [1:0] current_stream_portb = 0; + +always @(posedge aclk) begin + if(rst) + current_stream_porta <= 0; + else case(current_stream_porta) + 0: current_stream_porta <= strm2_ready ? 1 : strm4_ready ? 2 : 0; + 1: current_stream_porta <= strm4_ready ? 2 : strm0_ready ? 0 : 1; + 2: current_stream_porta <= strm0_ready ? 0 : strm2_ready ? 1 : 2; + endcase + if(rst) + current_stream_portb <= 0; + else case(current_stream_portb) + 0: current_stream_portb <= strm3_ready ? 1 : strm5_ready ? 2 : 0; + 1: current_stream_portb <= strm5_ready ? 2 : strm1_ready ? 0 : 1; + 2: current_stream_portb <= strm1_ready ? 0 : strm3_ready ? 1 : 2; + endcase +end + +always @(posedge aclk) begin + if(rst) begin + strm0_incr_en <= 0; + strm1_incr_en <= 0; + strm2_incr_en <= 0; + strm3_incr_en <= 0; + strm4_incr_en <= 0; + strm5_incr_en <= 0; + end else begin + strm0_incr_en <= (current_stream_porta == 0) & strm0_ready; + strm1_incr_en <= (current_stream_portb == 0) & strm1_ready; + strm2_incr_en <= (current_stream_porta == 1) & strm2_ready; + strm3_incr_en <= (current_stream_portb == 1) & strm3_ready; + strm4_incr_en <= (current_stream_porta == 2) & strm4_ready; + strm5_incr_en <= (current_stream_portb == 2) & strm5_ready; + end +end + +assign strm0_rst = strm0_incr_en & (strm0_addr == (STRM0_OFFSET + STRM0_DEPTH-1)); +assign strm1_rst = strm1_incr_en & (strm1_addr == (STRM1_OFFSET + STRM1_DEPTH-1)); +assign strm2_rst = strm2_incr_en & (strm2_addr == (STRM2_OFFSET + STRM2_DEPTH-1)); +assign strm3_rst = strm3_incr_en & (strm3_addr == (STRM3_OFFSET + STRM3_DEPTH-1)); +assign strm4_rst = strm4_incr_en & (strm4_addr == (STRM4_OFFSET + STRM4_DEPTH-1)); +assign strm5_rst = strm5_incr_en & (strm5_addr == (STRM5_OFFSET + STRM5_DEPTH-1)); + +always @(posedge aclk) begin + strm0_ready <= ~m_axis_0_afull; + strm1_ready <= ~m_axis_1_afull & (NSTREAMS >= 2); + strm2_ready <= ~m_axis_2_afull & (NSTREAMS >= 3); + strm3_ready <= ~m_axis_3_afull & (NSTREAMS >= 4); + strm4_ready <= ~m_axis_4_afull & (NSTREAMS >= 5); + strm5_ready <= ~m_axis_5_afull & (NSTREAMS >= 6); +end + +//one address counter per stream; more LUTs but keeps routing short and local +always @(posedge aclk) begin + if(strm0_rst | rst) + strm0_addr <= STRM0_OFFSET; + else if(strm0_incr_en) + strm0_addr <= strm0_addr + 1; + if(strm1_rst | rst) + strm1_addr <= STRM1_OFFSET; + else if(strm1_incr_en) + strm1_addr <= strm1_addr + 1; + if(strm2_rst | rst) + strm2_addr <= STRM2_OFFSET; + else if(strm2_incr_en) + strm2_addr <= strm2_addr + 1; + if(strm3_rst | rst) + strm3_addr <= STRM3_OFFSET; + else if(strm3_incr_en) + strm3_addr <= strm3_addr + 1; + if(strm4_rst | rst) + strm4_addr <= STRM4_OFFSET; + else if(strm4_incr_en) + strm4_addr <= strm4_addr + 1; + if(strm5_rst | rst) + strm5_addr <= STRM5_OFFSET; + else if(strm5_incr_en) + strm5_addr <= strm5_addr + 1; +end + +reg [$clog2(MEM_DEPTH)-1:0] addra; +wire [MEM_WIDTH*NMEMBLOCKS-1:0] rdqa; + +reg [$clog2(MEM_DEPTH)-1:0] addrb; +wire [MEM_WIDTH*NMEMBLOCKS-1:0] rdqb; + +wire [NMEMBLOCKS-1:0] we; + +reg [1:0] addr_select_porta; +reg [1:0] addr_select_portb; + +//multiplex addresses of various streams into address ports of memory +always @(posedge aclk) begin + addr_select_porta <= current_stream_porta; + case(addr_select_porta) + 0: addra <= strm0_addr; + 1: addra <= strm2_addr; + 2: addra <= strm4_addr; + endcase + addr_select_portb <= current_stream_portb; + case(addr_select_portb) + 0: addrb <= strm1_addr; + 1: addrb <= strm3_addr; + 2: addrb <= strm5_addr; + endcase +end + +genvar g; +generate for(g=0; g<NMEMBLOCKS; g=g+1) begin: blockports + +assign we[g] = (CONFIG_EN == 1) & config_ce & config_we & (config_address[31:BLOCKADRWIDTH] == g); + +ramb18_wf_dualport +#( + .ID(g), + .DWIDTH(MEM_WIDTH), + .AWIDTH(BLOCKADRWIDTH), + .MEM_INIT(MEM_INIT) +) +ram +( + .clk(aclk), + + .wea(we[g]), + .addra(we[g] ? config_address[BLOCKADRWIDTH-1:0] : addra[BLOCKADRWIDTH-1:0]), + .wdataa(config_d0), + .rdqa(rdqa[(g+1)*MEM_WIDTH-1:g*MEM_WIDTH]), + + .web(1'b0), + .addrb(addrb[BLOCKADRWIDTH-1:0]), + .wdatab('d0), + .rdqb(rdqb[(g+1)*MEM_WIDTH-1:g*MEM_WIDTH]) +); + +end +endgenerate + +integer i; + +generate if(NMEMBLOCKS > 1) begin: multiblock + +wire [MEM_WIDTH-1:0] rdqmux[5:0]; + +reg [$clog2(MEM_DEPTH)-BLOCKADRWIDTH-1:0] rdblocka[2:0]; +reg [$clog2(MEM_DEPTH)-BLOCKADRWIDTH-1:0] rdblockb[2:0]; + +always @(posedge aclk) begin + rdblocka[0] <= addra[$clog2(MEM_DEPTH)-1:BLOCKADRWIDTH]; + rdblockb[0] <= addrb[$clog2(MEM_DEPTH)-1:BLOCKADRWIDTH]; + for(i=0; i<2; i=i+1) begin + rdblocka[i+1] <= rdblocka[i]; + rdblockb[i+1] <= rdblockb[i]; + end +end + +if(NSTREAMS >= 1) begin: en_strm0 + if(STRM0_MUX == 1) begin: mux0 + mux #(STRM0_NBLOCKS, MEM_WIDTH) m(rdqa[(STRM0_BLOCK+STRM0_NBLOCKS)*MEM_WIDTH-1:STRM0_BLOCK*MEM_WIDTH],rdqmux[0],rdblocka[1] - STRM0_BLOCK); + end else begin: nomux0 + assign rdqmux[0] = rdqa[(STRM0_BLOCK+1)*MEM_WIDTH-1:STRM0_BLOCK*MEM_WIDTH]; + end + assign m_axis_0_tdata = rdqmux[0][STRM0_WIDTH-1:0]; +end + +if(NSTREAMS >= 2) begin: en_strm1 + if(STRM1_MUX == 1) begin: mux1 + mux #(STRM1_NBLOCKS, MEM_WIDTH) m(rdqb[(STRM1_BLOCK+STRM1_NBLOCKS)*MEM_WIDTH-1:STRM1_BLOCK*MEM_WIDTH],rdqmux[1],rdblockb[1] - STRM1_BLOCK); + end else begin: nomux1 + assign rdqmux[1] = rdqb[(STRM1_BLOCK+1)*MEM_WIDTH-1:STRM1_BLOCK*MEM_WIDTH]; + end + assign m_axis_1_tdata = rdqmux[1][STRM1_WIDTH-1:0]; +end + +if(NSTREAMS >= 3) begin: en_strm2 + if(STRM2_MUX == 1) begin: mux2 + mux #(STRM2_NBLOCKS, MEM_WIDTH) m(rdqa[(STRM2_BLOCK+STRM2_NBLOCKS)*MEM_WIDTH-1:STRM2_BLOCK*MEM_WIDTH],rdqmux[2],rdblocka[1] - STRM2_BLOCK); + end else begin: nomux2 + assign rdqmux[2] = rdqa[(STRM2_BLOCK+1)*MEM_WIDTH-1:STRM2_BLOCK*MEM_WIDTH]; + end + assign m_axis_2_tdata = rdqmux[2][STRM2_WIDTH-1:0]; +end + +if(NSTREAMS >= 4) begin: en_strm3 + if(STRM3_MUX == 1) begin: mux3 + mux #(STRM3_NBLOCKS, MEM_WIDTH) m(rdqb[(STRM3_BLOCK+STRM3_NBLOCKS)*MEM_WIDTH-1:STRM3_BLOCK*MEM_WIDTH],rdqmux[3],rdblockb[1] - STRM3_BLOCK); + end else begin: nomux3 + assign rdqmux[3] = rdqb[(STRM3_BLOCK+1)*MEM_WIDTH-1:STRM3_BLOCK*MEM_WIDTH]; + end + assign m_axis_3_tdata = rdqmux[3][STRM3_WIDTH-1:0]; +end + +if(NSTREAMS >= 5) begin: en_strm4 + if(STRM4_MUX == 1) begin: mux4 + mux #(STRM4_NBLOCKS, MEM_WIDTH) m(rdqa[(STRM4_BLOCK+STRM4_NBLOCKS)*MEM_WIDTH-1:STRM4_BLOCK*MEM_WIDTH],rdqmux[4],rdblocka[1] - STRM4_BLOCK); + end else begin: nomux4 + assign rdqmux[4] = rdqa[(STRM4_BLOCK+1)*MEM_WIDTH-1:STRM4_BLOCK*MEM_WIDTH]; + end + assign m_axis_4_tdata = rdqmux[4][STRM4_WIDTH-1:0]; +end + +if(NSTREAMS >= 6) begin: en_strm5 + if(STRM5_MUX == 1) begin: mux5 + mux #(STRM5_NBLOCKS, MEM_WIDTH) m(rdqb[(STRM5_BLOCK+STRM5_NBLOCKS)*MEM_WIDTH-1:STRM5_BLOCK*MEM_WIDTH],rdqmux[5],rdblockb[1] - STRM5_BLOCK); + end else begin: nomux5 + assign rdqmux[5] = rdqb[(STRM5_BLOCK+1)*MEM_WIDTH-1:STRM5_BLOCK*MEM_WIDTH]; + end + assign m_axis_5_tdata = rdqmux[5][STRM5_WIDTH-1:0]; +end + +end else begin: singleblock + +if(NSTREAMS >= 1) begin: en_strm0_direct + assign m_axis_0_tdata = rdqa[STRM0_WIDTH-1:0]; +end +if(NSTREAMS >= 2) begin: en_strm1_direct + assign m_axis_1_tdata = rdqb[STRM1_WIDTH-1:0]; +end +if(NSTREAMS >= 3) begin: en_strm2_direct + assign m_axis_2_tdata = rdqa[STRM2_WIDTH-1:0]; +end +if(NSTREAMS >= 4) begin: en_strm3_direct + assign m_axis_3_tdata = rdqb[STRM3_WIDTH-1:0]; +end +if(NSTREAMS >= 5) begin: en_strm4_direct + assign m_axis_4_tdata = rdqa[STRM4_WIDTH-1:0]; +end +if(NSTREAMS >= 6) begin: en_strm5_direct + assign m_axis_5_tdata = rdqb[STRM5_WIDTH-1:0]; +end + +end +endgenerate + +//output to AXI Streams +reg tvalid_pipe0[2:0]; +reg tvalid_pipe1[2:0]; +reg tvalid_pipe2[2:0]; +reg tvalid_pipe3[2:0]; +reg tvalid_pipe4[2:0]; +reg tvalid_pipe5[2:0]; + +assign m_axis_0_tvalid = tvalid_pipe0[2]; +assign m_axis_1_tvalid = tvalid_pipe1[2]; +assign m_axis_2_tvalid = tvalid_pipe2[2]; +assign m_axis_3_tvalid = tvalid_pipe3[2]; +assign m_axis_4_tvalid = tvalid_pipe4[2]; +assign m_axis_5_tvalid = tvalid_pipe5[2]; + + +always @(posedge aclk) begin + tvalid_pipe0[0] <= strm0_incr_en; + tvalid_pipe1[0] <= strm1_incr_en; + tvalid_pipe2[0] <= strm2_incr_en; + tvalid_pipe3[0] <= strm3_incr_en; + tvalid_pipe4[0] <= strm4_incr_en; + tvalid_pipe5[0] <= strm5_incr_en; + for(i=0; i<2; i=i+1) begin: srl + tvalid_pipe0[i+1] <= tvalid_pipe0[i]; + tvalid_pipe1[i+1] <= tvalid_pipe1[i]; + tvalid_pipe2[i+1] <= tvalid_pipe2[i]; + tvalid_pipe3[i+1] <= tvalid_pipe3[i]; + tvalid_pipe4[i+1] <= tvalid_pipe4[i]; + tvalid_pipe5[i+1] <= tvalid_pipe5[i]; + end +end + +assign config_q0 = 0; + +endmodule \ No newline at end of file diff --git a/finn-rtllib/memstream/hdl/mux.v b/finn-rtllib/memstream/hdl/mux.v new file mode 100644 index 0000000000000000000000000000000000000000..c5b89aeb4e7eb7b2858d062c18b693d9bd685fb2 --- /dev/null +++ b/finn-rtllib/memstream/hdl/mux.v @@ -0,0 +1,44 @@ +/* + Copyright (c) 2020, Xilinx + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of FINN nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +module mux +#( + parameter NINPUTS = 1, + parameter WIDTH = 16 +) +( + input [NINPUTS*WIDTH-1:0] in, + output [WIDTH-1:0] out, + input [$clog2(NINPUTS)-1:0] sel +); + +assign out = in >> (sel*WIDTH); + +endmodule \ No newline at end of file diff --git a/finn-rtllib/memstream/hdl/ramb18.v b/finn-rtllib/memstream/hdl/ramb18.v new file mode 100644 index 0000000000000000000000000000000000000000..7b207fbd6db7c9d985ba3ed50d7fcd97612e07f5 --- /dev/null +++ b/finn-rtllib/memstream/hdl/ramb18.v @@ -0,0 +1,86 @@ +/* + Copyright (c) 2020, Xilinx + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of FINN nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +module ramb18_wf_dualport +#( + parameter ID = 0, + parameter DWIDTH = 18, + parameter AWIDTH = 10, + parameter MEM_INIT = "" +) +( + input clk, + + input wea, + input [AWIDTH-1:0] addra, + input [DWIDTH-1:0] wdataa, + output reg [DWIDTH-1:0] rdqa, + + input web, + input [AWIDTH-1:0] addrb, + input [DWIDTH-1:0] wdatab, + output reg [DWIDTH-1:0] rdqb +); + +(* ram_style = "block" *) reg [DWIDTH-1:0] mem[0:2**AWIDTH-1]; +reg [DWIDTH-1:0] rdataa; +reg [DWIDTH-1:0] rdatab; + +reg [7:0] idx = ID; +//initialize memory +initial begin + //note the hacky way of adding a filename memblock_ID.dat to the path provided in MEM_INIT + //ID can go up to 99 + if (ID < 0 && ID > 99) begin + $display("ID out of range [0-99]"); + $finish(); + end + //MEM_INIT path must be terminated by / + if (ID < 10) + $readmemh({MEM_INIT,"memblock_",idx+8'd48,".dat"}, mem, 0, 1023); + else + $readmemh({MEM_INIT,"memblock_",(idx/10)+8'd48,(idx%10)+8'd48,".dat"}, mem, 0, 1023); +end + +//memory ports, with output pipeline register +always @(posedge clk) begin + if(wea) + mem[addra] <= wdataa; + rdataa <= mem[addra]; + rdqa <= rdataa; +end +always @(posedge clk) begin + if(web) + mem[addrb] <= wdatab; + rdatab <= mem[addrb]; + rdqb <= rdatab; +end + +endmodule \ No newline at end of file diff --git a/finn-rtllib/memstream/sim/gen_memblocks.sh b/finn-rtllib/memstream/sim/gen_memblocks.sh new file mode 100644 index 0000000000000000000000000000000000000000..05962f7be8fe4afd7790640cf4d280600dcf43d1 --- /dev/null +++ b/finn-rtllib/memstream/sim/gen_memblocks.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Copyright (c) 2020, Xilinx +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of FINN nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +NLINES=`cat $1 | wc -l` +NBLOCKS=$(( ($NLINES + 1023) / 1024 )) +rm memblock_*.dat + +for (( i=0; i<$NBLOCKS; i++ )) +do + START=$(( 1 + $i * 1024 )) + tail -n +$START $1 | head -n 1024 >> memblock_$i.dat +done \ No newline at end of file diff --git a/finn-rtllib/memstream/sim/golden.dat b/finn-rtllib/memstream/sim/golden.dat new file mode 100644 index 0000000000000000000000000000000000000000..1466271bcab961f742e242aea4241a4ffad02828 --- /dev/null +++ b/finn-rtllib/memstream/sim/golden.dat @@ -0,0 +1,9216 @@ +AFB2B66A +BB100CFF +1ED93E9B +1B8E800D +DA9E0150 +38B1C916 +93BC4E64 +860F8373 +B31D708B +C2934023 +739C9593 +4C898A3D +CCC8F4C5 +8FA275E6 +47732CC7 +6857ABF0 +31671013 +6BC4AA43 +73D4F790 +2C6158B6 +FDC3B5D +6DC755F2 +E0E7E8C9 +7862E17 +3D4FFE1E +9AFFF447 +C862FD7D +A4C4D89A +D7D6EF51 +10E5A31D +79DA9C63 +A83060A8 +EA988813 +6B411BCF +85544B5A +5AC91DE6 +586E6779 +8FE8161B +4C57CC92 +74C918A6 +36B20D44 +5CB62FC0 +62FDB2E1 +4B1CB514 +526B7CEC +B3FA61D0 +C95DDBE +CC2BA600 +2466CD1D +3354A056 +CCED3EAC +6FFA09EE +F9648FAF +18CB5358 +EA506270 +66F385A6 +5B0246E5 +26218A76 +BC7CECFD +5969F6FF +3DAF5901 +C53D05BD +1EDA2D76 +5C0C0010 +7A6C0C8C +BF99E997 +C964C884 +4DE417F4 +8637312 +133B8C3A +D637DB88 +297288F6 +CF1D00B3 +426BD0F3 +4D258120 +8F7EC898 +E15482D9 +DFDFC442 +16A5C4AE +7A6A14DF +5E9C2807 +31BD3EA2 +BD6DCDBC +E47CD35E +FA4FE42 +CCDE0036 +345EBCB7 +64686255 +AE1D77EB +D2B42B84 +CD5E5824 +8DABAB1F +4E07FFCA +7F3B4C13 +1A62C962 +CE08835F +E8E05318 +DC25C7BF +132E4308 +5D0122D6 +B7451ACE +829D2507 +19329C7F +39FCA8F0 +DCD1A574 +17E2EEE +B2B6583A +2181E65 +7013A2A7 +46535CDE +C85BF5D3 +2FD5EFC2 +E05C5D2E +244F0F96 +F01D711F +F1CBB67E +6DAE6666 +84AD6F4A +B95BC84E +9DD54B95 +5A7CA1B +7B1447F4 +44A8EDA7 +20929E9 +40E62E02 +3D03CC3E +81EEF8C4 +1E686D13 +17C13B3D +A14967BE +D8693E0E +15A7FDD1 +19F51C6D +249D0C21 +51424939 +BA05F551 +C614827A +32841A0D +2F8B041 +11A2806 +DBF24199 +F246D9EB +52FFB23D +F3061A47 +B6D51EF3 +2DE434C3 +E1D3F874 +85270B0A +CC405B14 +DD3E9F23 +A0352F98 +67EE5731 +96892C65 +6D67A443 +16354414 +17959F75 +A554F236 +C585076 +2B665011 +7D503509 +77A4530 +6A13C8DC +31996F5 +916AD400 +E761D000 +D23CFD32 +CF3A5154 +C575A1CB +B91ACDBF +BEE7F338 +44C26212 +8124CD5B +245F7451 +DD6D18BA +6B838EC6 +5247AB98 +2F41FDAA +A780BD3B +1FD2F95 +6CDA39C +C31FA5A0 +AB56A5E1 +87F50441 +47093971 +BEBD81EC +2A7F6977 +8C83BD29 +FB067DAC +5FEBDCDC +8FB43F72 +EE45FC6D +4088691C +34F235D0 +43AB8E4D +67FA8BB5 +FC2D2C02 +DA77044C +22E6FC7 +6B6039A9 +BA6E3C45 +46DEC612 +8E7E0FF7 +438DE467 +F4525025 +7937973A +9ABE4BEF +8F8DF841 +F74C5087 +7EDE1CA4 +FF3C7F98 +A025FE0B +59E5EDF6 +6DD27411 +65C080E6 +C86D872D +628B6B26 +B9316D56 +E09EFA8B +A8CD3F21 +C0CD8745 +F4D62BA7 +D4D7FB99 +E9174232 +7F068FC4 +767480FC +275BBBF7 +3470FF88 +E632ACD1 +85677507 +AE0E2C69 +E2C74DA9 +C307B72B +5FB5A769 +99C18162 +FAFB7660 +6E984733 +E17FD97B +EC5E6CA7 +3D659815 +30826B60 +300BE8E8 +86D0B096 +856F2CB0 +2A61ADE4 +24EEB996 +2FCB729B +8190CE0D +E64F7E6A +4D0D42F +CE29765B +C77DE893 +9264C299 +A200E419 +868B5EC6 +8452AC39 +59F7BDED +422E75B2 +74E6329A +38F053E8 +16F8BD5A +363A2E43 +8018AB7B +44AE4CF5 +C8F7B14B +52658A45 +7B46C7D8 +CD319C38 +19AC8957 +5F42CFAA +5DB4DBF7 +DF66DDBA +4FBCB611 +266DFB86 +4F0EE64C +1765E724 +E30C89CA +4705FCE8 +BB7636B3 +789EFEFC +AAC0F37F +424B1661 +234F05AB +1BC0ADF8 +7F9EC67E +500448E5 +BF4D1C45 +C5B64E3B +914F44FE +EB17F041 +1752165C +F5B72E31 +6D68C060 +4EF27C55 +8CEDFDC5 +E3996A56 +25C5C632 +430D930F +EE04DE4D +576E4921 +E13A2A6E +CFE21675 +B1067912 +4C888068 +3C3A1A6D +FCE12E0 +FAD6AD8B +F7DE2E0F +E8DC0DE7 +CC8721DF +34411355 +2C664D07 +ED034324 +F57FDA56 +8C70BCDF +3A6FF2C8 +C6440537 +8113D976 +A40176A1 +46D1D0D9 +877A407C +3FBCD395 +3E74C1D8 +72E22A13 +BA46116D +CFB14406 +21400896 +7AD34367 +2905F60C +C1F9C16F +2E0E5FCF +2EEB00A0 +9C2D94A9 +8DE1CF01 +5912596C +CF2CA22A +774E7D4F +805657AE +1BA223EF +236FD53F +C1ABFD4A +6B8DD778 +6A6E40D2 +70CF4F79 +950E8D35 +5E4F9545 +86AA4166 +28D056E9 +9C550D75 +CB435A3 +B875667E +F54E6E97 +BB7ACD6B +F11637E9 +C220E1FA +C7CAD54B +32853439 +65BA20C9 +1838F8C0 +C3CCE57D +7D2B69F9 +137AD6E9 +6C041B9 +296497AA +98C5E853 +D37AB835 +376764A9 +2F714011 +D24BE867 +B2BA4E +9EA785F9 +726FCED6 +6B4C6950 +44C6D5C0 +85DEA727 +733F5A86 +41785CFF +BB395E8A +100F8117 +276A08D3 +9268A16E +FBF63C19 +AA497F25 +E92E1DC3 +185B4692 +FE6377D6 +C50771B +D98BCD04 +50FC7D74 +BE5BC294 +2C9C4482 +12FBF6CD +D1E04AE4 +5C9679EE +889D2695 +3699F061 +933D06A9 +930DC367 +496D7A37 +C4161D19 +3E08728B +66388C70 +B2363734 +5D12926F +39B4AEF8 +1948B925 +321E08BC +27559FC2 +A543B709 +4D28BC0 +46C64305 +F7B7D459 +97C4966B +A027A9C8 +43CABFA9 +F7C3643D +1128AB2A +AA4A1419 +AC6F2B46 +8F6FEFEF +34284D4D +D951EB81 +77AC6B7C +70F6E0B2 +FD7BE3CE +77BE497E +4883FBD6 +FCAB08D4 +9BC032A4 +67DA8A5C +82037EC1 +E3EC6CC9 +481B7623 +DA1F3873 +CE9E8787 +785CD654 +1661CF27 +42BD0C3C +990F261A +49F18930 +FA336094 +FFD6FC06 +B71077A6 +204B911E +BA1586D6 +8A2F6DBC +36B184AD +76017CAB +DA7E891E +88A51A1A +97AC49CB +2482BE28 +CE6BD009 +C7776DE0 +4E960944 +64081AF2 +56512D55 +D6D1C640 +EE78145B +54CC5EE0 +BE5D3E1F +8FC8816C +1D6AC407 +5D98F8F1 +18FECC5C +F3DE9A29 +93A19068 +AB623B35 +43FF1A02 +AA26434C +B071FDD5 +45AB6A2E +C1275AA7 +EADA5CDA +E427C95E +AE6E5B77 +89F3CA30 +9648C00A +330A03A7 +20DB35D6 +AA9946BF +A0E3050E +DEBB5819 +5047E2E +9C8FBEB9 +6B70D173 +8A99428D +230C88FE +3B26DBD4 +8DBED704 +EFF1C946 +C2381970 +71087497 +2268599D +FCE50AAE +460A49E5 +EC65BC4C +5A83C23C +DD44120F +D6E81BEB +D10235B7 +9362A387 +B3C9220C +46F21F0 +3D04FBC0 +63A2B38D +8F7DEF26 +F326457D +21933DC1 +775197FB +8D6C7C5F +B2D7D570 +147F9FF7 +78666356 +BAB7D249 +69B45EC6 +F56634ED +34738794 +26DF0163 +188DA00 +D2035A36 +FFBB8062 +62852DCF +55FC882A +849388E6 +43BE6E2C +D53EA2A2 +A228BC21 +9112A960 +5FCDE2F1 +79F42B27 +8AE37179 +1D722815 +5AE6DD26 +A8531C6F +EF386673 +AC761B14 +23C6BC3A +488D93B +AE6B0D63 +A4F1CEAC +43F80A43 +D9681EF6 +BA959674 +CCB852B8 +D9F4D79E +6403622F +75FAECC6 +7F43813F +51FC7BE6 +896A3A28 +CAF31C60 +76000EE7 +C1135AAB +6E83B2E6 +2AED1966 +C4F88A86 +21219EA +8AF14AD6 +14014BA2 +BC0BE2D5 +78757CE8 +C09D83DC +6B2021FE +D5AD900 +3685A49F +FD8B4BA0 +7B005539 +2F0C36EF +B41DBA0D +1DCF61B0 +CB3DA1A6 +24C0ADAA +BED01B2B +59C8C334 +11CCA76C +6F962508 +ABE672A6 +3C281A24 +A6C3DC39 +A72517B1 +FBA81175 +9906CEE4 +E8177FE1 +338D0184 +CC6650DF +840D8CA0 +4C55C42B +6B40F9CC +57B7E7B7 +B7C42442 +4500E9B +8C788183 +9B8F5FCE +49D0AEE1 +426B2271 +EC25BCE3 +7D63A976 +2EFFF592 +32A9E43C +AF5AFA52 +3ABE1133 +35B75ED7 +8F4271A9 +725A6EF +7ED7EB40 +37BD3B +7A0A5AF2 +F6492D7D +C2856688 +9595C241 +C07F646A +7D394FDC +7A991B05 +2CE3AF30 +9929E6E6 +4AE66BD4 +F0F3D1A3 +F76F72E9 +6C2051E2 +72431DE4 +B1796A93 +E04FD748 +D19522B1 +71396A78 +4202F058 +4F2CEB1E +A186853F +8B4474AA +C679B644 +98E10D42 +E7CEB08C +733CA225 +3478B95C +A706A842 +9510B8EB +F47E426E +9A0A17EE +2DA8832B +E73536CC +E6CA4B40 +11A2708F +753AC1E1 +8C304DED +5FC83F07 +4F9A04C9 +E0737708 +9091DFDD +8E1B322 +2552D768 +7C894296 +EABDC081 +E3B2A37 +DEC7EC87 +37FFB6DC +2B2A0CD6 +7E797B13 +64ABD0C5 +1FF12252 +F81AFB24 +C16F1ABC +F0B5AAFC +F80281BA +E51C04D +EEF8BD3E +450A49DB +AC985D7B +CBD4D077 +CAA6370A +FDA6530C +20B71F06 +ED5A891E +BA51A622 +E9F8E132 +63C23719 +2F59EE96 +14D77539 +1A98FC31 +12FCC937 +F39AD8FB +3750DBA9 +564E45B +F74C47FD +1010AD3A +8BE0AED3 +28B27F7B +D5E8EEFA +DC0EFEFB +959F5394 +A10ECCB8 +5C366706 +3B82A5EE +74E377DD +9881CEF3 +D1A4BD88 +69106661 +B209B42 +B56EE86B +63F37839 +C5AB7736 +4AD627C4 +8A4C7E1C +F7CC6334 +3D6CAEC4 +A86A18D5 +8FD910B1 +972371C8 +A423E9B6 +CE8C76C7 +DF930841 +C9D4A7B0 +18521955 +F6F167FC +889F1625 +432C606A +CA5EB4D0 +AFE77C91 +EAF55F16 +6F9A9777 +33726C1D +DC7B1D64 +8031DC00 +CF13144F +84BF2AB +45F5FD45 +6AF06D8C +C50FBE6C +11B8A4A2 +16B780E1 +98033979 +8EFAAEC0 +DD984A5A +D6A80AFC +15C793A3 +EF458063 +B784551F +552CC380 +D1E05EBA +4A795261 +F2B25418 +66066848 +D935B481 +136D2C8F +7A25AEFB +7000439A +E147CC62 +68976C6E +69447DAB +C72506F3 +C6E3FE3B +4FB0FD96 +DB465740 +A254195C +B11EA223 +FC3C44B5 +A9A86F1C +8EED03E3 +24CFF3A +A1B488CE +FD75D002 +9FEF0461 +75DC6637 +B3D38CD2 +57C8F65D +C62026D0 +D6320A18 +5E961798 +80FE0097 +6DA57E68 +D1E8A3C7 +96D49CFC +A8D2DFBC +520D2C1 +151C3F1D +8180DCC7 +4461E43E +C895BF5C +18EE374 +33EA06D4 +75B9D006 +23B934C1 +C2E89F39 +444BCB75 +78077AA5 +ECA64716 +3C1E3FFD +F7DB9CEE +6EC313DD +9CABEC47 +675FA281 +16B8304D +3E38FEC +A9663BDE +8EF647F2 +B646C61C +2228E400 +2B411566 +7A72EB44 +88BD9AE9 +4EF4EBA3 +BCC822D9 +4668160D +695667C1 +CE51A675 +40DE9687 +877561EF +416F5AE6 +EF9304FE +34C1C9D3 +5B63E1BB +C50E9899 +1831810D +25DE2CC1 +10539A77 +EE51D9B2 +462E5A70 +B0F8C3B7 +CA16E410 +1796F2E5 +573F6B28 +E157A965 +2640969A +153B4909 +7FC1290F +ABCAC2F +2A42D17 +BFFA3865 +7B12D8B9 +9321F9EF +E560B7A9 +36E18DD2 +57710FF9 +FAE1F933 +F717FEF8 +E86BAF7E +D0CE3E89 +C8755650 +704BB6ED +6309F650 +E21DDB4F +7CBF531C +7E0AFB8E +D6A1128B +60F16A1B +534186AF +72971F2E +428A867C +F571D32C +CD522E7B +13F6443 +38CDC9EC +D01C51E6 +2E575D3F +7E86B596 +C1460B28 +1403B019 +76D89A66 +4F2D9465 +9B87B1 +172A00A4 +4669559C +105C8A19 +3CD2DD63 +EF054D76 +8B9AB48 +64136500 +71C56349 +B7AEEDF5 +4145D7AC +D6A3E4C7 +2F9E0DF4 +31E418C8 +D2C839DE +63E919D9 +2F4D0353 +8812C572 +B88E671F +54D2BBE0 +E166998 +B7487741 +64312607 +5ADF6F3E +31A86BF1 +D8A96C85 +22AA3021 +AD4719B5 +49EB0670 +93B76AAF +B109648 +FBC7346C +2530A7B5 +C8525175 +15EC0A76 +315FACCE +D8C21A6F +9EDEF96D +6495575D +722A0577 +51EDE2ED +8109F168 +6CBA0929 +1ED88DCD +D79A67E2 +CE62A29C +6FE2A87F +D1E6E3B9 +601988A0 +6A045849 +A7E30F35 +E0EE4424 +AA89C628 +33D7A7A3 +FCD27B7A +80CAF9A4 +2E7F1302 +69F19C +80DBDC64 +392FBDC +E5981A33 +B4AF4210 +1DBFDB9F +31E5DF02 +5C571556 +EE256151 +9F573818 +200D540B +87743240 +1335188F +5A1E9D1F +FA267CB +688D2302 +80D32C1 +195719E +EF151174 +772EEC93 +DD2E2E4E +D8EA362D +3B24FC06 +FFFCF7FC +C571F2F4 +A8DAC7D +3BA7880C +16FC184D +7DBC453C +8F355780 +65C7ED3D +2202E50E +9EC765A9 +9D8F8CDA +CFA71D0B +7A463A33 +AA94D750 +359750D8 +B9A4BEFD +B153CD8C +93AFB5F4 +2676E0A0 +78C0805 +347133 +3B229F4D +4486A7BE +F3A0FAF3 +D29E9349 +A62C0FB4 +574D3763 +BCDAEE6E +BA27D40D +896903EB +8AE6171C +A911D78E +970FB490 +33B8A631 +893F7E3B +700EDF9D +EA7AC6E6 +6041F473 +FC6702EE +F225A258 +96A21B4 +CCA94D4D +FA6D00B7 +35580441 +F5E42BA +EE9AB535 +50874EBA +4454B2B +30653468 +9ABFE240 +29A13784 +EBF5F88F +B1769BB8 +EF22637D +A2FEEE4E +4B39E8F8 +38AD4316 +A3FCB454 +7D6F402 +18CEA9F0 +956B2CCE +6559ADC4 +F00F696E +C878E2A3 +3AB31BE4 +FF2E6E3A +3767BE32 +37CFBCBC +C307A74B +ED6A132B +8D5A1B70 +774C41D1 +A45F1CA9 +3FCF576A +C1BBAB8C +5B11B23A +620B6C8E +A6F5CB83 +450BFF8B +FBB9620D +BD936B56 +2FBF9A89 +2E000CD5 +E508C955 +2FB99422 +5043B664 +1C43CF3B +2D7E713F +FAD8A72B +7CF2FA33 +8FDD90A6 +8B5CDCDE +6CBF908F +740425F6 +D142F4B9 +2B30DF9D +3808D354 +508C4729 +E6FB0279 +FA0F9DF5 +2FFA33E1 +8A93B18 +FE7C0855 +E69193B1 +AA7E4DA +DCDD121D +4E7CD1 +14C03D9 +ACB60232 +818C10F0 +D8CAA46E +2CBC53B4 +46F82991 +9B24E92B +E1DBF265 +C6649C +87D0CA2F +C24A605 +AEB470E +8DC36FE7 +2D6B856E +9B459A3A +5C204000 +C7CC0BA9 +E637D8C4 +1F8C7240 +41788DF4 +27B94DFA +BBA5B2CD +51E1AB57 +FB14B16B +B6821713 +F955BAB9 +44FEBDEF +A484D04E +FCC08A15 +A117E11E +CAE09305 +789A734A +338EAB60 +183825B +61931C6E +ECBBBA86 +1AC53895 +BCEFB579 +CC68D938 +217A4ED1 +3CC6F2DE +12E55EF5 +FAE1CE98 +CF89DDCE +8FEFFF33 +8C27552E +6D63AA8F +B094E27C +4E7632FE +5D9DDBD8 +8E2766E6 +2EF9333E +98B9A7D4 +20D98AB +C12C8047 +5995F2BB +BB30E14 +C769CC0E +632D8C76 +B7FBE051 +3170D046 +D595ACCF +190326FC +D1D03166 +DA4420CD +81FA57FA +D8615FD4 +33AEF793 +E2B32AB3 +E2B2D613 +5A37DB74 +EBF473BC +62C5F8CF +624D5D2D +9A9006D4 +8515BED2 +7DD650C8 +D0BABA59 +1E635B2C +690CBFF7 +E4028EC4 +E4E5B3C2 +57607B0E +D4087B2 +3C06022A +813133A2 +B206699 +3827A132 +985BF479 +6C11EA62 +F58DA68F +818CD2B6 +F204828B +64A0D011 +A6F07C40 +6816D54D +8B00F959 +3B6A1891 +EF20520A +B5B90BD0 +D70B3B4 +7B165E3F +FBE60B95 +50656296 +6250C189 +B50E29BC +7BBB35AE +124AD7B3 +BAD38F67 +A0CA136 +FB03F6CB +B88FB36D +9025524E +4EB80454 +D07FEA2B +D9385E1F +B1EDF69A +11D2AE5C +9EEC00C3 +55916263 +AAD5CF88 +2740548B +662FB2DE +173DFA86 +8D734BE9 +D4A27E13 +E92A39A2 +A58A3F4A +A71CE9AC +B43ED5F +1600E2AD +265C4182 +4EA4F91 +1E3A0BD5 +62650FD0 +BC6E23A1 +3BF3E963 +5F6AFA4A +6BA2B659 +5C00047A +E8F81B0A +C30BF4A0 +DFF059E0 +4E3F93FE +D688F348 +3220541C +F8A72F57 +6D78CAE6 +AF13AA11 +BDB3229D +936DA76F +749DB9C1 +EBF347A6 +BBFA776B +6472B218 +6144ECA8 +E66CD255 +274BC846 +64C0C67A +95748CF2 +25DE3E48 +29A685B3 +CC8C7B15 +F18FA7CF +5F2D1C01 +6DFEC90F +CF834DDD +A72D9439 +BC6D83C3 +9F888C34 +385D225F +168886B3 +98EF8EB2 +BD8ADDD1 +80DA0EE2 +F4196AC8 +6F020F21 +61136480 +4DA28475 +86A506E0 +1A75F4D7 +222C4645 +8C4486EE +98560E3C +944205C9 +D5E0BB3C +C9667421 +2932030 +BFE65EB0 +FB463370 +9FE77763 +DE8ED32D +FC9BDBEE +FD77E3F +288C605F +7475F3D +C3F75513 +C5AF2C40 +40FB62E2 +2C7C83E9 +A8A7E6CC +512E4560 +950C9D +EC507007 +65B7CEC6 +4A91094F +3BDA586B +7029FB6E +739B556A +678652AD +7B940AD3 +4A8728BC +76841FC0 +F53DEB4C +1B13B0F8 +80A5CFA8 +69C8B602 +6F984889 +14A53B17 +409BF6B7 +46D597EE +3502ED7D +315B1DE7 +E785791 +21871730 +78BE7E05 +D1536BC0 +F9708FE6 +EE4E143D +4E498B00 +A2113F88 +630DFE4E +3FA3D4B +F88D623D +3ADB0736 +BF25AD18 +CB89D619 +1D41D458 +EEFA6367 +7671EBAB +B98E8CFB +238D9F19 +C5155B +223C16B +E484FED9 +DD6A6680 +5192089B +CFF24757 +F2CD17B3 +CC3C7B1C +581E6ED2 +C2D7E5D2 +E9789543 +424EF913 +E6B10C7F +706C0B16 +6EC36BE6 +54C41CF4 +CD1EAD0D +17460ECA +452A78CC +D680E5A2 +57AA8EB1 +252EB084 +9DBB8E55 +BF759D75 +6E5E9F27 +30EBEFCA +C4514A4F +FE76382B +99A07A25 +F9017D0B +452226BA +3DD6111B +967464D +C0BAF41B +C4D39425 +767A57E4 +7183FC19 +844A33A5 +54F13F7 +C5854DAD +BE406FE9 +14340FCF +F665DC28 +701D2EA1 +A7B6AC6C +AC3167EF +C3CE6810 +C6844D77 +64887D7E +4EFF4E1C +8508CD3 +45CD4361 +3FAB9023 +9121F935 +46C5C6BE +272C83A9 +24762973 +EB858013 +FF2D23BA +6F5C8026 +A045E967 +7B844395 +2611E8E4 +8AF4659 +89FB4D33 +D9F50DF4 +CA6BD0F6 +A47A1386 +F78D3515 +2E73ABAE +36C0297B +DCF0FD32 +3930C7E1 +246799B2 +BF8BEEAF +7AD6D40C +7BDCB9B9 +7829D32C +EC826EC9 +ECE1D576 +4E3D613B +DCB44DB2 +67EA1BF2 +D1DE75BF +4609E175 +423132A3 +D33DD5F6 +D74829AF +FE0FB1F4 +C32939D9 +4FB97597 +1441DE62 +649D26B5 +4835C073 +1F67EAE0 +E28AE826 +DB808A84 +58FD0074 +1424245 +6BD9E7E1 +26476595 +E8C08661 +F1F0D3D5 +577263A7 +CB86C426 +EA57839B +C8B37BC9 +FBD2B525 +D033D0BC +A3A0474F +22EDE40F +CCD58291 +CB64AA7D +3176C162 +78DE2512 +ADD0A1B3 +EB41F141 +A7B5DAB1 +C68652ED +1F8E90D +31578AF4 +CFA12A8A +E20A88F2 +74AA9676 +3B353B5E +1956E731 +AA8B10C0 +63369269 +C833A9E5 +9425A8E4 +89DB1783 +1BE23F63 +D84221B9 +F8D9FE9B +EA1FD309 +E16516F3 +8F0EA801 +F5256123 +F21B02D8 +F3335520 +F7729F5D +B7F2AF17 +6B97F182 +806347D9 +962A011D +A5427014 +B7358896 +E9D6A1C6 +2E3DBDE7 +94B06EA1 +4B3D9107 +26F1956B +1726E033 +6660681C +39E4E3D5 +E8CD4742 +78D71E0E +15733521 +89D0606F +D449755F +A2753DF9 +AC7ED71 +7803B9A9 +87CCA2B4 +23003317 +2A91CE6 +C37B28F5 +CD9A436B +893C12E2 +C1FB04FB +3D8230BC +737002C2 +15314ACB +F4D74B95 +6C8BCBFC +292459A8 +1692BDFF +DC68FEB8 +48DEF854 +4BAE6B50 +8B850B23 +AEDD7125 +5B740DA0 +AA83A652 +474C59D4 +A4B2D4D3 +451C3B83 +D93BD101 +BF10B243 +8AB74771 +68C5891 +C8EE35CC +D22DC638 +5C7FA2D3 +54A2001A +747538DC +AC75ECD3 +F1BBFFB4 +844C0E4B +D7D25E9E +460EC0ED +688BA8D7 +CA6E35E7 +9396DBBA +3E9C3E0C +5D29B720 +3E5BB85D +F1CFA9A +8EF00E21 +28669B1B +98BE145D +2696E360 +F91E3763 +B0E3F6FE +45699C1 +F5945549 +2CB64CA4 +F3508C44 +653BABD0 +773F51CB +9D228D81 +E4FAB747 +1DC767E3 +89A77290 +8E2A722 +45D00328 +42E979FA +C19D28EB +C6645B54 +5AD41E9A +93587C5A +719944B2 +B10FF0A7 +A57FE070 +78C8DFAE +138BFBAF +1126A4D8 +C9DB256B +EE01D5FF +A8EB81AB +80AB24B4 +95B129FD +802078 +A6F71D37 +334BFF82 +32678187 +4AA896B0 +149226EB +5B8C446 +D1799EBD +74EA35A0 +FA9B52C8 +FAC6A436 +9E543685 +C1184EE +2D8CF846 +C2AFF300 +18EED386 +80C04036 +77FA6FF7 +5D1512F0 +D2C0C9B7 +22DBA873 +62468BB9 +42C90933 +F7EA7A3C +69449140 +7DD1B0F0 +52AAADFF +2F8B7479 +70B719F9 +CD8E1081 +4B46932 +DB933B74 +1E7A04BF +75DC735A +C3925701 +7EC84718 +DFEE049D +E8B3328A +3A9936EE +F2E22D2A +1F2B5894 +DB44DCE5 +4F1DD5B4 +B66F3E9F +943480BE +ABA71BB2 +E4F15D5B +4C9D7A9C +B751518B +24C9762E +F9DA3386 +D13AB9B6 +5CFC891C +CBEDF3E9 +395421ED +5A3570B8 +1641D0A0 +AF9A9981 +A07CC659 +4BA92C0 +D94C7431 +AA749489 +372456FB +690097AE +B5EF28F3 +1F8F313B +6C45ECE2 +24F4CAD9 +40C5200C +920AFACD +A2E0DD6A +CEC81C6C +DED2D22F +4AEA1A34 +7504D5DA +1F8E8F02 +72100835 +BB4AE282 +A0154848 +EF3ECE2D +6DA87A1A +46D17BF +DAE80D31 +FA8CA757 +8F75F943 +AFFB5EDD +F1A09255 +A80EDAB5 +5AC04A14 +B51A2E1E +FD9C51F4 +F99A5A90 +3EA5F0D +C4D40DFC +C0280AF9 +CEC83127 +FA1A5F6B +D603510E +3663D878 +A79682FB +B7313271 +7E37A2C7 +A1CB289D +C51B6F15 +EC66F0DA +80D5C268 +F3A52A28 +E056F895 +4A0A2418 +66E47974 +8E8CA911 +FD7E6D05 +70960317 +5D378166 +3A2D634 +CA6510C4 +93BBB6AB +4FE2CF83 +2273B7D4 +E372BB74 +8AD6B40E +496AA885 +11F4186 +8DEDF498 +5435E535 +5145EF8D +44AB3DF +7B449D2C +3489063E +F0A61E35 +A2F75775 +F691A0D2 +9CA997F2 +D64FFFB7 +DA79CC6A +2DEA4171 +D2E4D598 +C641D01 +79699CD2 +49FF5A89 +C967A1C4 +F4C7FF25 +9CD04F9A +374C3740 +7B6376BD +ECC505A1 +E76F3618 +42C0B205 +B28C63BC +2BA4280E +7278103B +83B861F6 +F862D563 +433B3F81 +358E4226 +2E9334B5 +2E9B7324 +23BF3CB0 +1E44A323 +BAA2480D +3B8483BD +419659C5 +91A9B2C2 +82574F8 +28A32CD0 +3534C89B +759FD52E +B260329C +82112334 +2D5B7F7B +816C0227 +ED5FAD1D +7BDFA5AE +B5C8006C +BD9691EA +36C28C33 +B8702558 +EB3E656A +D752A865 +FA94FF5E +AE5D43C3 +747587AD +6E5E5C96 +39312BCE +B13B468A +81543486 +1B57D2B3 +4D3D70A7 +2D4ECFBA +640E83F8 +4FD1588B +4EA4599A +E231E4F0 +A2D4437B +47D88CE6 +D048C6D1 +4CA7F923 +E9E435A8 +E93D6805 +C032C4A6 +E15934E3 +CB728ED0 +E7D65CEA +8E5D2F8B +1676D174 +B42D23CC +A1462E09 +CA718E2A +F5BA8F57 +EFA467ED +6DA31185 +895FB4A2 +649A7D89 +3B71CFA2 +C67F9D02 +DFBDDF09 +AAB8BDDB +870C617A +220F7717 +795DE75E +5C787D87 +BB94CBBC +99928778 +9D5C4DAB +4EEC433E +F4C08960 +F71FE87B +BF78D7C6 +671FB341 +4EAD6A0E +534B1D46 +1B4DE7CF +A7B45E06 +97F43041 +4B77382C +61EBC96C +336A9206 +E2A6FD02 +72E6EE51 +26144F77 +DD22DF66 +CBAFB596 +B9CE864D +CEBC372F +907981E8 +A9FA3C97 +6B1704B8 +B1160637 +FE603AC4 +274C6ED5 +6C317434 +77A16703 +2489D28D +2DBFB899 +4A3D882B +E81AF570 +1B8F583E +F1CFA601 +C7B776D2 +A26651A3 +303D5E43 +CD80678 +7E9DCEBA +E0F128C5 +4B1807BB +25B10534 +4117D98B +95079C39 +58C7BCE2 +AE0AF4E3 +331A0152 +DB3D821C +F4F11B78 +E2F55DDF +15BF23DA +15E7695F +1F40D321 +128A49CA +2D25CD8F +AE762164 +7EC8AC49 +1D9A1899 +97B6BAF0 +D7E07736 +A2566738 +A903EE89 +67CD354E +89C1C57A +97B3EF5C +240FC35D +52CE3A2C +15E8D7D2 +6A8A9E32 +4254550D +A345B8F1 +464C5420 +FD2E1DB2 +C629DA54 +81D24EFE +421E30F4 +E4008742 +62839D68 +AD78257A +23DBB6EE +49DAE0F2 +B1B07AAD +EC7791BA +3B4D3E2F +C241836D +C836E98A +EE9D6DA5 +33B5A570 +81D50D38 +6EE68232 +76677B3C +AF355302 +D2415D7 +1510CCAA +A6627F82 +A5A96453 +CD0B833E +5CF4C1E1 +C14866A +AFB8FE0E +B7D08BAC +4CBFF97E +F0191C3D +4E2A3EC +E76E048 +FF368683 +F4DF51 +8D0F29CD +91E431F5 +B6808051 +927E3404 +6ADBDD1 +5852A1E9 +394DFE4 +8990BE64 +A69026EF +3656791E +63C5AC11 +B9E88670 +9326F9CC +414EFA53 +B5028CB5 +22181175 +3B1A49C1 +22FEDBAC +A39731D2 +9C7E2E87 +E931F133 +D9AFCE3F +C2CC527A +A85B19BB +C66CB9EC +93558B54 +F5197362 +7EA88969 +B380F206 +56AC8890 +56D0C8A6 +B39C42A6 +7B966768 +1B6E37E5 +43429273 +668BAF0B +327CE28C +CEA34DC6 +EA727DD9 +2C1AE3E4 +802A7A51 +A1934827 +1A18C4BF +AEB9CA99 +D572EF76 +18DFC210 +11A4385C +671ED0D6 +D1E5D02E +9EE0AE12 +DF1EC812 +51BFF4B5 +CE089E79 +CE4BADF4 +75879327 +C98B6178 +D7B1E852 +95D6767 +1283D091 +20F90A2C +9020BD75 +504D84DD +D8982F3B +E41E0CF4 +55F4FE2E +2097DB6F +4B8B7790 +F3A1E487 +F4C274C1 +3452A00A +15587F21 +687D0671 +7EB3715 +945B9A90 +8C83F0D1 +8934F9BC +38A50D8A +7EF49EB5 +A45D34E3 +6C014201 +D4D19185 +821E216B +569485E9 +6DCC7357 +7711858C +852AA907 +591CCDF4 +775E7DDB +9463CA74 +DFF1EFEC +1F60E4B +2628AEE4 +EC89EF52 +49D232FB +E8BD7DD1 +EED418A8 +C35E3A33 +5C739CE7 +979E4B23 +B386E4FC +62F98F10 +2FEF090 +599508E2 +F3F9F428 +17A18287 +639B700A +AA9AA4A6 +B1AFC9E7 +FB6E8D34 +44F6A6D9 +EEFB7788 +9D616EA3 +78F3BDCF +A5E71361 +1D25ED7E +9059ACA7 +89118CEB +BDE78C2E +55B9E0E4 +FB6B9A +2DBAC44 +85C0DEFA +1E222914 +2413FBCA +C8569486 +E757EC3C +5ED9DB70 +3EA2086B +F4A4057D +E29E1B00 +C271490A +525A60E4 +9A286CE0 +61A42BC0 +D3F6ABE4 +9F31FB75 +335ADC59 +9EA61808 +232ACBB1 +270C7B13 +6EA6535D +F1D1B1A0 +AE9088BE +D9E4FD87 +3C8C0972 +5EAA57A +26997EF4 +3B02B885 +A4722715 +434BE51C +495165DA +BC9FC978 +18D8C1E +328203FD +12643D32 +65EFAAAF +71297EEC +EF8496AC +E5B7BF16 +2B2C5A0A +86B713DD +101E03D1 +14F4FB7E +34EBDF2E +2A9F4CF5 +7143B386 +448716E5 +C61C8469 +5F9F797D +6A89B910 +548E4139 +C48968FC +11F52973 +E18DC2B5 +7EEDA069 +2EE38156 +B8F99E97 +E066E1BB +ACC5C04E +6E645848 +98CA4890 +78191984 +84EC83C1 +C58D9987 +3AA63D1C +E17CA75A +CF8B5E23 +155BC19C +5809C3C5 +E2A7DAE3 +D55C1B6A +585BF6D2 +5D192255 +310467FC +ECA8FE97 +4ACDBA8C +E6319F8B +FD4F3E85 +47FF7B0 +B6FA3B69 +D75D49C2 +B831D3F4 +1D6282B8 +E335FE0A +C955B98D +87968F47 +B9600C1 +805AB6DD +2677ED62 +86AA7680 +836DD1B4 +82C073FF +F2664656 +DBE8C3BB +E4DA24B2 +AE14BE60 +1CF178AA +F2C661B +9ED5C4B4 +3B67F448 +426F85E0 +40195BA0 +66BDEE57 +3A128638 +A48D546B +7DC7834 +C7706566 +1E23F578 +CF55EC28 +F46031E2 +CFDD3546 +6CD58E9C +C40E02C2 +19558D54 +46E056B2 +C1581093 +20C057BD +34695F72 +1C4B7B13 +2FD3155E +152F2F86 +189E2F15 +31991472 +1B85405D +D1F72A1F +8AA93824 +CE409894 +9F6D30AD +E72C6DE5 +A31CC799 +694EB42E +C2D96633 +7F4776D2 +509C0781 +6A84F278 +E11739F5 +CC5EFAC4 +DDD81D37 +6960145A +E40C5DEC +70C068DF +1E6CC338 +592EDE93 +A19B8534 +DA27B1C9 +608D85FD +63AAE798 +509A13B +BAF29F05 +69342538 +5A2FD47D +5FA22C82 +AC7E3397 +4E546537 +4611C427 +DA39FAAC +445F1CE8 +5BC83B69 +64AB6C7D +F2B4EFB5 +DC0016AF +987EDDC1 +3354C952 +A5B9ECBD +E5B77548 +997279F9 +7C460F6 +82A1099 +B7CF0472 +ABC3726D +DD4155C0 +319B8C50 +CAE7E88C +910F1C5E +B1367D8E +56B78305 +8F4CB7A1 +8765A3AA +89624EB6 +22DE29BD +A12D4C67 +6BC56ADC +B587BB0F +3806EC0 +3C269C48 +9EA289A3 +B5EB4FDF +1ADB0729 +A991429C +CE574FF8 +CF071DB5 +CE0D372F +3D99AE5C +D6D56E7C +3A493434 +86AC7C63 +FAF8B585 +B9F1994 +89CB3A3D +7C8974F7 +2169640E +D74D62DA +8F0D850D +3B9D0225 +4E2CBB6A +BCA7006 +9DCE6E7B +3695D660 +EB344960 +F3D223F5 +6B8CA588 +45744961 +2F493968 +E9CBD376 +9B0FDE95 +F17603FE +B0825FF2 +5B1CCD35 +6F98639D +5CBBFA88 +890B3C42 +2DD4CA67 +DC9513B5 +A7B91C22 +83A897B6 +399ACDEC +AD11B2EF +11D76C5E +E170FB03 +9326B999 +87845BB9 +CA14B73D +943FE9FF +341ADB81 +D800A2CD +A7265DEE +1E7F3F7D +8AC49BD1 +CCE49B1F +58764B66 +D57DF0D7 +229BE279 +42DB683C +D8530314 +F1FE931 +DE1A4EEB +DF35B43B +3E90F80 +B3934E4A +FD658EFA +E6CF1CFA +472B47E9 +20F155AD +77571441 +9FE03233 +8BC0043E +80E9B238 +D325F7D2 +F0333147 +FC86E62F +A5451DCE +D9374B52 +674D4083 +9952E9AC +B529BFF5 +B7E072D6 +5BCD2886 +8381AC4 +5CD6C7FF +F24E3549 +9EBB5EB9 +23F47A79 +49D578D0 +6CA5874A +2F3C83E6 +D975C720 +FB484F11 +3BCFB5C0 +3A66DB47 +B3BB4F33 +D5136C2 +D4AB89C5 +8A782859 +C8FE9ADA +B5D57BA5 +9C8D2781 +7D0919B5 +D362A6D6 +1006FFAA +3BB31D71 +7709BEE4 +8A348C59 +44A704D7 +96F2AFF3 +592DF706 +F3247289 +3E9BC2A8 +570D8349 +2F615AFC +B3802616 +B54191C6 +DD155718 +455945B6 +C74C7DF8 +232005C5 +6185D2D2 +8FACE1C +73D27EB +770D2680 +DB913D28 +90FC0FA5 +9DE358EA +2BD3287A +D5C8095A +DE541F30 +D10F0F61 +4657627D +739F2E93 +F9F7B479 +DFC6490 +3D554A13 +D3C6C2EE +80145765 +D601408B +52EFFD8 +A44B597A +9E65E39 +2A5CB536 +A0420638 +EA752AFA +A7DE4743 +18480882 +A559B83D +2DC4B6C +8F33055B +7C4E3B8D +52C7F9F7 +9FFA0A63 +A0413C90 +ECA35002 +AB4A7AD9 +A829613 +71904BCD +9560A35E +118EC2D1 +CA730775 +A631E447 +F526588 +C415CDC9 +DE509745 +C2C64E6B +4A3350CF +CB04DB23 +8D3BA4E2 +3FC18EC6 +C8CFB2C4 +C2B600BF +FE36BBA5 +EB4B302E +F2BD24D2 +A820E2B0 +DDE54189 +744E33AA +9E63B141 +21C2E601 +2C12D5AF +85AAD794 +EE1F97C2 +9096006 +14132FBE +FDDA365D +E3623A52 +9F52F94C +18F84D8D +F866F6EB +9759E208 +38195047 +E31F1936 +9D7E9182 +CEC2787B +975EB96B +12F202B +CA36D8E3 +A694168A +F033E484 +DAEA79C6 +C465D02A +154EBBA3 +FFE408B5 +977F7FD7 +59992C2 +72DAEF3B +47AD9078 +11CEA76E +3B88B352 +BA2FF2D9 +2A7F4E47 +DD6B398A +164FCDDE +CB7284FE +9FCF9606 +34406791 +104CC89C +A2F32BB7 +213E9CB0 +1E1E0B37 +7226FA86 +20502886 +4C1C9E90 +2D4D0ADC +D843214D +57730409 +614341B4 +ECF30446 +330F5216 +5FBA2C4F +B4102EF6 +D6129240 +7D5DFBEA +EB01FCDB +7CA7342 +46DFED3F +5BE1B2D8 +2F40EF9D +59622E77 +A6AEA365 +78133A87 +7FEF9106 +3956BCC5 +8C6509F9 +79525FD +D3A518F9 +A76193BA +3F552EED +F974C309 +12A5B04E +A71DD6D4 +D9FE2B7D +95F822BA +EDBE32B0 +92BFA916 +79899BA5 +3FBDC933 +BC0E7C30 +6D7FEA47 +1F1954E +4F2F17AC +F6EA71E3 +B8E34FFE +3BCD8BD6 +695B7934 +D4CE8358 +26B0699 +784EC0DD +625BC98B +8861D087 +44DF0DE +35B7517A +A8FA9A12 +244B927 +AF7A58C +BE48CF00 +95C13C21 +9D8DBCFD +AE8B4798 +ED04535D +47A2219C +C8B87734 +8355D2A5 +B4127CD6 +DDA3394A +36846F2C +F38282D0 +177D3FF5 +EE8924CA +5E6CB3D2 +1F6C2C7F +3EACD843 +51A77194 +51D89AA4 +DCC17C24 +DB5043E9 +25D52B74 +1C7176E2 +1F483DAF +24B587EA +6188E94F +C886E2F7 +7B24254F +A761DFA7 +357C70B5 +6BC46A7 +31B8CF7C +BACB7205 +6C1B0387 +50685794 +7726ACF +64C49E4D +7AF06B7F +D1F2AD02 +E4F5BB37 +2A8A4925 +4245E047 +B7CD8000 +6C72A8DD +19590349 +7F7EDB49 +5DAF5458 +5EEBC5E9 +6E84757D +AD3868FA +F85A2B5D +A8569A1 +88F1F6BE +AF363178 +D9A61BFD +A2959EC8 +C1343E46 +B34A697B +22530AC3 +70213F56 +1DDEECA5 +4DF030F3 +78A4B8E6 +F93B20A6 +27AB7A7B +F43A2969 +AEB9E421 +75A8F820 +52CD9316 +CA166F29 +C28D14E7 +51E4C76A +50249FCB +3EDA432D +C6C3EEB3 +6CFF2A56 +5B50A9CE +D2CEB19B +2F16746B +1C19CB24 +9CD2076 +3F804860 +FE59323F +62F1F95 +2CF56FAE +E1A3437E +973F442F +DB62AE6C +C0AA4F87 +67224779 +A28378EA +6C5BE4D5 +97F75FF8 +49922E2 +19ECBBCB +C89000E7 +436496D2 +29C94230 +21A4D75 +3DF46E1A +A6D150BF +4EDE1CCF +37A996E3 +B0F73D3C +33E41F15 +14076103 +7BC6082F +E98E377E +1E787464 +16AB93F5 +B8E3ECD1 +4A944320 +41E77D61 +8B669E91 +20F1F65 +F4D26572 +81D9D4AD +99843F88 +7066E60C +4D6B9549 +C79BBF94 +F53252E4 +EDB94B9F +EA504F01 +9BE5AD3C +98F301D4 +C1C0ED35 +3F2734C7 +76351C26 +AEC02AAC +B9D4A014 +A01F14A1 +2DD27A90 +27C43590 +5A06F84E +64CC23AC +76387C33 +A07A8306 +3BC362BF +5ED88200 +CA6DC828 +4DBF3E47 +F633C85E +96F44176 +76B2A46B +CF414D71 +AD77A07A +9A1F71BC +FDEE86EE +7A8AC33B +AD3C257D +BEFBD214 +5B562E2C +3527654F +FAFCD066 +575BF8E0 +BC2A071A +C903C2CF +EB1AB30 +7B8C7CA1 +5ED6E493 +E1C822C6 +368B9DDE +91122C29 +5B1358F8 +6DCADBBF +ED845AC +61E42CB5 +732B420B +39154876 +C10442B5 +E1CC1A11 +875215B9 +AE9E4FEC +B2435F4C +DBC844A +10FDB0DA +F85D3FC4 +608B78A1 +DAE2B7B2 +DCD08039 +CC0962E7 +10602FA7 +62522FE1 +D3AFCD9D +2882BAA3 +70C31CD3 +A69E9A2A +975BB834 +2A35C91F +5FB2644F +69B2BF1 +9C365DDE +E4199E06 +ACCF8904 +DE105FEB +9C07AC45 +F75CF55 +EF6E3E9C +1FB088A2 +9A93BA86 +4E91C403 +E07827D7 +5F7593 +FC778EF4 +5B831E07 +354A60B2 +8D39DB34 +5C3C16CF +38489DCA +D83EBDED +F9E5BE76 +D2C7FCF3 +E868A2FA +D29E98A9 +5AFBCA1A +D01628BF +B2334643 +4EC99A5C +189E9585 +CC2B18FB +C692AC25 +A7F6B978 +C1530E03 +AC815E6 +6304151C +52EB83ED +C4921682 +96441A15 +56338D69 +5C82292 +FCA308FD +978D2310 +192DB3D1 +CA6B9EAA +7AD9F05D +E7C35D2B +AB5505FB +3DD6013C +532AAD00 +87EA4F8B +1AC88F4A +4BFC2053 +65356D9B +B03A54FF +6F585110 +2C75F6A4 +CFDC2733 +3E7BD30C +2DE068DD +F318385E +26CEC150 +532C4D5B +B264C41E +46229E71 +39E85376 +A074FDB6 +461E84CD +BADDA454 +77D4AD4E +479457C8 +F0E4F65E +DBA7730A +24D4FEE1 +9442683 +7725F0EA +F8647367 +5F4D5208 +6DC11B5C +4E65BE22 +EC0713FD +1D54F605 +4B0F99DD +E585AB57 +E14C5EA4 +B7909465 +12ABA66C +EEF519D +62F4CFD1 +48DEF31F +16B38659 +5528B313 +5C031870 +87ED6DE1 +55ACABF2 +FACEBE99 +3007B9E5 +F5C0C90F +E97F9A15 +951AE375 +67E41B2C +CF7F6BC3 +C7836B7F +88B077DB +DA60BEA0 +1FD6BE04 +95A08F39 +B7EA73B3 +10F6685D +A9C04118 +EAC17020 +CEEDC89 +7EFB007C +8D900B82 +4C2BCF1C +9B9BDFC5 +28846A96 +139B4D19 +32E0786A +72F19BF4 +66D61EB0 +609F7568 +3A785E09 +B6F2294F +96E73FE3 +99A0812E +1BBAE42 +9DF477DD +111FF2F7 +8A882B32 +2542FA4E +7BEAFF22 +405268CA +2427EDE6 +7D9F0726 +7EF6ABC7 +7F8DD904 +C3F2F4AB +213FB22D +62AD3732 +955CA4C7 +9E83055D +BE9C70CD +C0E6DDF0 +892D1B64 +56F3A648 +43547D3E +35EB967E +EBC18CA5 +D4DAC35A +9DDB564B +6DFD4F07 +CB02555B +425A1595 +B978D512 +B3D78E9F +A3EA970F +8E27124E +6A57B7D +26D405F2 +C8A1CED7 +7A6338C +A497AA49 +95602B8B +C6F1583D +CF5B6A58 +81F2D693 +A34B3C07 +B7180B4C +46C6E5CC +8C3736E9 +980482E6 +8A34B532 +B698520A +20E9DDDC +A5D8B27 +6A0B3989 +10071434 +C82002AE +8A343B26 +2FD61FC8 +C1257546 +FF154858 +1AFEAE33 +C2B1532D +D979A2DC +93F9FD3F +769B0DDF +4132C851 +A372D4CC +6A5532FB +E8F203C1 +A421B3A0 +B50F5C9F +AE5B067F +8CE6F896 +8BFFEABA +B0CCFB51 +D455681E +FDEEE781 +A4873A97 +E3FAC8DA +5039A29 +C703A1CF +E4E29AEE +39C0B0DB +DE5756E +303C7D43 +586246C +41ADBF9B +D1CD7207 +3BC8FD94 +7E50A650 +390914DC +ABD6170 +ECFBE529 +3D51360 +569802B4 +25F255D +1523D176 +9F98AEF0 +9DB1B681 +DAE01D8 +46D4F7B7 +47DD8DB6 +23BDB9D8 +90C47F30 +998BF564 +5D60F7E4 +309B5851 +9D246C3 +C1895130 +1F918DFB +6F303265 +71E0D0A7 +77F2FF64 +589BBF0D +A25C4510 +9F05AB6E +4990B583 +D335BD7 +6CBC0400 +D7894817 +36176CCF +1C6A98BE +53EE793B +4003C3B3 +9E46BEB5 +57647A51 +D5599FED +38156D3F +B1F425B1 +7AD6402D +74B619BE +A11B18AA +9C4211AF +DB076668 +7A94C4DD +6833F9A5 +A088A4AE +6A70BAFA +BC6740FF +B7F6508A +F3BAF225 +29BF8108 +7F074F1C +18B3D5C1 +8A948077 +BE0483D3 +46B195FE +D7AF0FD0 +C31414F4 +B5BD4871 +CFAC4C37 +57D2D42C +10A73F90 +407A80A8 +21C50A11 +22E165A0 +8361F9A8 +EDEA52BD +28F3650D +CAD63254 +9AB9033E +82BA1020 +E6E6A470 +9C829847 +BC3AB877 +A91A7C99 +1ABAB07E +583AD9D7 +9AFA901C +9AE116AB +27B4F5A6 +877D0225 +92DEB3AB +BAA1506D +EB04B325 +C275FBF2 +2331B6DD +74F623AE +933EC4BD +9470C6AF +6C0828EF +AAC0532D +318961A +29C176E6 +4011BAB1 +895DF78F +410AD703 +F363E54D +B4913DBE +6B5047EE +E7099A72 +E2961301 +E587CAE2 +1449E31A +EB048AC6 +D21BCEF +EACEF00E +EF09B5C6 +2C050BB2 +D660ACA0 +361BA74E +26D1A92E +10F1FD22 +DAD028BE +5DDB96F4 +A1C8F873 +66F44797 +DD6019B +618F707A +4E4525A0 +551B89EA +6A93FE33 +8219D90A +5E3E3FA6 +C9C25F24 +D4593D42 +CB12B9FF +B09814CE +DAF289CF +C59234E7 +6C96C435 +1E7337A5 +FE315E60 +451A4E00 +CC3E2B8 +EB1AABDF +B2D1AD85 +2A12A008 +B525A4EA +ABE700A4 +80603A44 +3E2E49F6 +48630509 +9673204F +7B0DEAD3 +B0B2B6D2 +68C0453E +BA31833B +4BD68812 +C64D0638 +A8987E25 +48850A6D +9B337E66 +1D99461A +D47AE0D1 +2E3023F7 +29CD452B +A211306A +15CD90B9 +D5D57C24 +727FA881 +51316FCD +BF62F735 +9E67B311 +51A2B90F +CF7C9936 +A537087E +3EB2EE91 +8F4D2C93 +F83E1906 +826C14F4 +6CBE676 +ED2DF931 +38270781 +4C567B1E +96BD9972 +E089656B +7DD03E9 +534E777F +695B12CF +338EDC74 +D5E3DFDD +13937C2C +A386AB68 +CADAD94A +B624A652 +9E4D0656 +3BDD26F4 +8B9D1ADD +180D5005 +E8744FCF +6CA71503 +20697624 +49269DB9 +B27B12B1 +AC181CE2 +9289684A +E5D3A21F +6A79B5AE +EE6DD5DE +355DA7A4 +C5B13162 +5FFA0324 +602F32A7 +85BA4032 +DCBEE18A +D76BFC80 +4B72BA0 +4101BC2D +A3CB1CE3 +4C6262A3 +59198E3D +AAD7C84F +4DFE129E +E8153DB5 +66EA03BA +D3247EB4 +750DAFC0 +68FB3A27 +67005B98 +C2255031 +1D9106CC +7FD4C833 +491CF81A +28D5F0BD +E2275FB1 +762FF58D +D9D940D7 +C6B5CBDC +810E0D6B +DAFD7E89 +15C3544B +D7B6A237 +3DA125A3 +3272795 +A7BCF9DD +4FE52CD5 +3FB69C23 +4F106EA9 +3632D2EE +9DA08D3C +5282D2C7 +9575F24E +D390A80B +2897EB0A +A4B9FBE0 +DA3FD83B +EAA2A95A +73FC7AEE +CCDBF4F9 +3EA97EA4 +A8AD7E75 +C533A490 +3FCE73 +D451BBF2 +6A71BE12 +76E1EC5A +1845E1F8 +CD2B7C0F +4D92E7BD +81B44E4B +65E1B458 +6B69FD73 +86CE76BD +88B1CA29 +EA1F0D7F +43D393F9 +C85E394 +B5C665F0 +AE373F77 +46196293 +E6057838 +7C63A634 +C3F66075 +1F15C3E1 +ED457843 +83F9BA3C +D8B8A399 +852DA2FC +3B81F785 +DFA3848 +877B985B +1C82BEF1 +6482EA27 +A4F94E9D +9FB72748 +47CF963D +C514BF88 +4D4B79D +232D2991 +3DEB3B5C +49784213 +9D79AAEC +EB89F7E9 +B9F9993 +71528CF1 +E1390DCC +F4655453 +97847A30 +3C30D55E +72649CB1 +F0647A6 +C6C8AC04 +FB48D1A +39EA9573 +70C70D43 +3F6BAD93 +342ACF49 +F37B506D +EE64D0B3 +4DC05CFD +79E116BD +5458D922 +3957971C +970D89F1 +9AF398C7 +A9A651DF +D3A64902 +27339129 +2FCC3329 +B1C70D5C +3FCCAD9E +C10A34 +80B546E +7EC04275 +512434B7 +526742B7 +E96DE8A8 +27CE6F9D +FD566C7B +8DB1FE12 +93F810FE +C660877D +348D5704 +BB3F2FD7 +9F859C53 +907BB57E +318DA95D +BF1CF416 +3E8BF68B +BB8CE4F6 +A9954212 +D1A396D6 +C33F5A44 +2DC0A59D +5B66EF45 +1CB288E0 +D6874F40 +E275F00B +E6B62E72 +6BB1EE97 +389CF9D6 +8C093ED1 +D4CB36E1 +12F4840B +F18A2F83 +782EB525 +12BFBACE +78F772C4 +91988F79 +55BE57F8 +6605D204 +5A7471F4 +355005FE +267A8C9 +CAB49590 +9479E9EA +BEE93B2A +34E95C45 +61788682 +6B99ED61 +33D4D3D8 +DD149E5D +D3BED775 +287B4087 +A2552A0E +477D609D +96765321 +2696E220 +3B6E26E8 +5CFFD0A4 +FDBF561C +4C41A4FC +B0637D44 +85DF60F0 +539171DD +9A1D1F12 +72ADB48A +D8C0C9CB +E4FE15BC +24EB5C50 +E1A9B3DC +360563C8 +F20C02CA +E9FBE774 +B2FEE97A +EF34194C +6DA8A0E1 +ED9FFA1 +4EB5D717 +47D296E0 +FA147414 +C1F868CB +761182D1 +6B9F8311 +7A99903C +95449FC9 +A349B21D +F2AA6E8E +CBD733B +1EAA2224 +C7CC9CD1 +DF3D1C7F +81343E5 +30682CA5 +65C5BDFE +811D5CC5 +8D2DEF35 +D8B4F4DD +9E121109 +FCA97592 +99E76951 +7CFB5D +8489CBDE +D7A8D721 +ADD1A5B5 +4A96DA59 +CE6C2C78 +17593D2D +F94AF7BA +6CE767D0 +DBCEDF25 +43629583 +CDB11A86 +BB630047 +8A579D2A +FC17AF19 +ED54597D +9BCAA00 +B7865C74 +BADFD092 +9AB0AF05 +AE371DB7 +EC0EE641 +A9781E96 +D1B8A429 +FE9A2043 +BA4C2CC0 +F243E36 +78A88066 +70925DF6 +97A35A05 +F18822EB +212A79D +666D7F82 +4558A3AC +FCF953EF +F8C6DD4A +C535BE4F +973A007C +4DB7E662 +C8995287 +B3527C60 +FA4F7A3A +D417AA12 +D861531D +11A81498 +5072EC65 +5886C667 +7EF848B3 +CA4ED80C +3DAEA7BC +34EC1028 +349C86EB +6423A583 +22A163C +339CC766 +E93138FD +7A79EA77 +E480913 +1220E06B +65ED8DDB +ADF487D5 +82CAE485 +A88E6546 +3A7F5961 +4672ECFA +425EB8F +AA3C4450 +44CA10FA +B1EAA942 +9EC93584 +E417CBF4 +B5F4C488 +EAB1DE5C +10446170 +C5F9C89A +391EF7F7 +10C62C73 +817FC74C +DA1A9F17 +FA38D673 +D2026552 +D7CD67A8 +4E0E21A6 +56812AAA +1D7294ED +575452A3 +90581C22 +82E00D73 +A8FECF07 +1CB1E500 +7F51D70F +F840E8D4 +DD73E72F +8DED415A +3F029F0D +C9CC871A +3388492A +AA1DEF8D +F2E93846 +F9CC596 +48221BB4 +6F7B2734 +F5A1010C +C0FB41C5 +8693416B +C8EAD749 +21ED8A7A +9FF52520 +613635AF +92C5E0FF +435C33AD +2550A70F +B17B7FE9 +9CC5F28E +690D4EB3 +5C5DCAC4 +25E14191 +B03B4C07 +50DCF2C0 +499BCF9A +5CCD6CF1 +ECBB2C48 +A2990792 +2105FDBF +3D62BECB +493AA5F0 +2CF5BAD2 +DFF53D23 +50D77C82 +35CDBF8D +E3BD4C29 +6A2FC510 +A9B2D0FD +404B053E +BF548C52 +E52081D2 +AD550AB1 +D4316A79 +776E6C42 +203A4395 +54DAB8DE +EB67FB95 +46E34074 +21679614 +C395F6BF +6D513D56 +93DDFEE7 +7D2866A +2283CD12 +12789536 +5C1F1037 +4170B23 +8BB451B5 +A9915ACA +784C0FE1 +50A95654 +CB574A +8A1690D5 +D9753D9A +3084718F +8E429880 +D1B7693E +A7613422 +C1707E97 +D658E57C +1C2A8F42 +21BE34EE +E545D5C3 +23DF7522 +B7AD16A3 +C6E7279A +2AD251D +FF0BA8C9 +E586EA40 +D86C394D +1A0D6737 +5AE27469 +8A0F53FE +1A0DC5E9 +8A56C2C4 +AD3214FD +DD999E92 +E53F55E7 +5AB39BDD +119C7046 +19B8238 +E21A4F81 +5DE3F0F9 +BFB5E145 +5020F616 +C2794F78 +9B7D9F3A +8FBBF3F1 +1D9C111C +49FEEDAE +1C83E386 +BB5B0273 +C290FD8 +52C788BC +86C12DD3 +6608E8F1 +313C6430 +142570B6 +F75B9552 +C8F1E8B8 +F3E5AAB1 +9E4D9E8A +7E48E48F +2182FBF +F21DC3 +BD6E45C0 +8DC88EA2 +D5B67DA1 +C592692A +979B0A6B +783D09B0 +C2231CCF +5CBB3057 +4C10986F +3F738112 +BED7BBF2 +A2577A6D +13128005 +3C71262B +BC8E920B +40C44CC9 +C6C4B496 +5AA9CBD6 +C7A9741 +2A8EDC58 +D2253A26 +F343439A +13F71CF9 +A4BB5CE3 +FB52ADA9 +1AF0749E +ADABA787 +C22B2194 +C5132023 +846C2188 +33A64D52 +E5CE9022 +CAA4C044 +E7032B82 +30251130 +22463302 +954AA98D +52D6F132 +11E0FDD7 +D62BAE17 +9844BF8B +68ECD60A +E637BA92 +1D7BA1A7 +F091F891 +CC96CCF3 +E2C50AF4 +149FAA77 +F16F7294 +27212569 +B96E1119 +E7806734 +15A5818F +4E05DAF0 +F022D5A0 +303D930 +B92CF71 +377DE596 +8835F16D +2D0B6E77 +2A89FF6F +9EA75369 +FCDF31A7 +8F674B8 +34D270E7 +BFE6FD70 +F165A645 +675B8D2D +318F8DAB +9F52E28A +A464F277 +B998CE45 +9E932DF9 +2918A97F +EA5C5130 +952FECC3 +7DCBA50B +DEE7C01D +96B96F4F +1C6106A0 +85A1AC4E +D62EECAE +6387F846 +271EB1BB +E1A2582 +D1E03035 +9EC6EA57 +300E10D3 +CB91419 +52652E8 +8291BE30 +E1D52680 +5044FC2D +35E58D3F +C6A01A83 +814DA7BE +97A50A83 +DB801411 +D4C43BF3 +BC3D29C +E4A072E8 +6F51D4C3 +21A5886A +F744A91A +5E12BC21 +F86FDFF8 +C320E6BC +3DEC9656 +F89A6364 +F668339E +44999436 +F40A8A0F +71837448 +B09D47B3 +2D2CAB19 +3FF04F12 +D8E5CC71 +33F39593 +160D74D7 +FB841949 +95F0E78B +B9A6102A +A4D3C679 +4774D90A +AC55693 +8F3CF617 +5BDA2B57 +A548BA77 +B1158C29 +FE9A4D00 +B52446D2 +E6DA1712 +3EFF4A4A +41EF9936 +D65FB56B +E3AED57C +BFF89053 +192E499D +DD703817 +C2B8C9A2 +65A8417 +670D3446 +2E936BCB +8A14CEFA +CF71A41D +842BD0E9 +628148DC +9733E864 +1C57CF93 +1A0CA311 +A1E13B05 +2C8F3844 +66C2361E +8981A417 +A4668A3C +271048C3 +6DD908BE +1A933D24 +BD0A78F8 +57C44DC3 +1EE04ABC +32275D51 +B25BCCC5 +509C83A2 +E5E1B85F +D45DFB17 +EF39D3BA +4F4F32D2 +8F1E52D +62A47A4F +7E4010A6 +189250D7 +CF3B51EF +5E9BE373 +E9719F77 +B2741A6D +CF19D7BA +993284DD +A1839978 +AC00E790 +ACD3A888 +1E74292 +6306A56B +F9EC26A3 +9FC5BC2 +2D6F22F +8CAAA98F +CD2135D6 +D2F5CD5A +CFCC3D48 +6AF7A18F +5A3EA067 +8DE9498F +A279E5FE +8C1D89E2 +5D15FE82 +AB291798 +40421279 +E101CFFC +D2D0D57B +5C977DF4 +68D4EF4D +22C36080 +81526010 +E5A41122 +160C517E +8BDCEC09 +5F12637A +F3714AF4 +D21C140F +B1EFABEE +E49A3E48 +E67BFC93 +C4BE9508 +21854565 +60757AA0 +FB5C43BB +150F6634 +115BE267 +3BE8F3E5 +EBF986EE +BA18FFF7 +82B52CF4 +50546F93 +118CCB96 +AA6603F1 +F434B7D1 +FC356F35 +C996ABD3 +CC8CF7C9 +4C2935D2 +2DC9EB76 +ECA4D776 +5D2D35A8 +7C747824 +ECAA990E +A6078345 +CF589355 +7E9AEC63 +859E12C +C2F31842 +6563A3BC +D43FE9EF +39D1717 +AB887505 +1AADAED9 +3D07A0C +7D2B456F +53C1B39B +DF349267 +FD9CC686 +5C1CB396 +89DD96DC +A0D8DA69 +F2A68012 +7F40A406 +1DBF2E24 +B31EAEB0 +5D5073EA +19C16D03 +10E50F00 +47D3D228 +A3C0E13B +5E801D5E +C58677AC +F6E9095C +E2C0938C +14CB070F +11B98703 +9FBA36D6 +5ADB369F +681BC767 +BEAE4008 +5A0AE129 +ACAD1673 +F9992AFA +2CA14EAA +F77F77B6 +2705BD3F +F9C3E6D6 +D3ED854E +4A5FB85D +54187218 +B9B8C83D +EBD38F57 +C0D17CF6 +8B464900 +3F8D26CA +C0FADB4A +7F79A367 +123EEC9B +99B683A9 +157062A4 +91DE43EF +65733625 +56DC9E5F +2C88A8E2 +83AE236C +DDBF0A9C +18873E45 +5040B3D7 +29927CA4 +B5A18202 +93CC4EA3 +5DC2F698 +A97A1713 +A104C149 +B9C5588A +AF182A52 +CFEC25AE +CB1C0A91 +143A132A +27C4A3B9 +D73DB7B0 +53AF7F76 +9A614866 +82A54DBB +D77A5A23 +AE3FA285 +8C2EEA1B +DD21D577 +186EBEF7 +DBACB855 +18E30376 +144A1FCD +773561F9 +F18F3C71 +4A13E021 +8738BA8E +1A9FF053 +56A546BF +860C6457 +9E5F2177 +B3CD57D8 +7A2CAF5E +F8D57DC7 +941CACB +E70A729F +7EDB09B5 +E972B09 +ADB7C542 +3832A659 +AF33DD9 +152082D4 +9A2A3452 +70B5EDBB +C6549E13 +D621FFE8 +15152F3A +7781B485 +67B0DEA1 +C787B62B +75B9A705 +C2A30FD7 +41CF8EA +3D2B2148 +CA0445C0 +802799F6 +FCBCCE57 +F539ADB0 +54952BE5 +B343804A +25752CC0 +3F276012 +7228715B +7F61944C +DCB8676E +132DC654 +CBA2782E +33016B92 +30F194E +F2D953D8 +15A92EA +495D2D8B +4366F311 +8F8DC099 +C4B2611B +D90839F0 +CEDA9833 +5CA78F56 +5D5F4751 +7F37FE54 +5B8F6537 +6B89CDD1 +6728B0EF +D2BED44C +60293190 +F41CF0F0 +8BF08F76 +861F32B8 +2053AB98 +315DF7D5 +58BAE934 +F38B7C9A +653396B3 +E2152002 +A4E66BCB +C1E3F151 +AE7AF50A +545F0684 +643CF8AE +BBC4B464 +7B8F849C +334A660 +3FFF02AA +7EFF666D +F80965DF +42D34429 +B8037A02 +36CA2FBE +539208E3 +D03932C7 +5C619FA4 +FC641E3E +D01051F3 +51DF9226 +116CF628 +8055029F +4A9130C9 +5A2701CF +89251BD3 +52D99785 +B2C16C02 +83581080 +57D8A09C +6D551FEA +EE6334BF +7D8061F0 +8556CEF4 +D9418360 +82DE39D1 +AA9CAE96 +8D3C1056 +8C67B490 +C7BA78F +D46697F3 +879107FB +88F4FC5A +E7B0C68A +3BD94FEA +648EAA00 +22724D11 +B6F00ECF +488584F7 +A104F52 +FEE79F3B +689DBC3C +2DFDA897 +411EFFAC +546F5C25 +45562F46 +C17613D7 +40CD3300 +9908DC56 +5AE62418 +4A3C1C82 +A28631C4 +4AA65060 +5614DE71 +6512AAA2 +5AE841E7 +B04094A1 +AA8F8123 +593A95CB +21919833 +DFFAC729 +106727F1 +273A2977 +85E6CD4A +E9751C6F +DC308E67 +40F7722C +1D8986DC +489D6002 +7A869A39 +6E02A88F +A04E30C2 +B98C740D +3672EB58 +9702EBCB +2CD4FB56 +A0CB2C94 +47299608 +6BB5451D +36EB4DEF +763593B9 +40029F5 +9392B153 +777DA521 +3125CFB6 +E60A4DE6 +98B9CB40 +819091F6 +83D23CD3 +ECE09D62 +22EE60D5 +29A3F86D +797C0E72 +1EC708F +76F78D62 +E527F0A5 +F11AD3D0 +BBF11E9D +5E944B45 +D090FFCF +4B8F7B5C +96ABDB47 +2F5379A2 +38FD509C +F49D4D2E +F5538B3E +BAD3E277 +E9C9831A +22D3C209 +CEE03CFC +EB55F3D7 +C61B5224 +6C4E6ACA +A63B52BD +695DBE54 +3C68D8AE +847F8449 +72B426E6 +95642CE7 +B021A768 +AB094E2E +90D8A573 +D3BFF1FB +460DD461 +EF32D23C +868AEBDA +6BEC2EC0 +34D18392 +6C9D6621 +6CE02624 +75E6AE8F +B5BE7494 +A033B3BE +EED6D471 +99D40A8A +BC742254 +530DDD69 +77698872 +E89F0ACA +39716DFA +C811D562 +FA7770AC +1F68B8E +7D325ECE +8CD870A9 +DE561FD2 +8D49A512 +979F1346 +CBC53E73 +E779994F +354561F2 +ECDDE60B +52EE9980 +46AC0C6F +555C8C8E +D382E1DE +2A9A602B +4F18FA80 +96068D7F +D1E5CBFA +957912AF +DC0A3107 +77CFB940 +E7161980 +EB44FE07 +C1597F4E +FFE737C9 +ECBD5506 +AF75488F +6D0BB14E +9ED0A181 +8EF54B6D +4E69EFD +9337A7B7 +A880D3A7 +97A5D09D +FD9F77A +7CECCBB1 +2869D0F4 +F1806C1 +F9FEB241 +7D368AA7 +FF972C5E +FEA0C745 +CC1413 +DD4CEA96 +FC8C6CEF +75727E51 +5A17C784 +422EDDB7 +6505031A +5662B865 +D7848124 +A93A9AC +D874DF58 +FEFDE7F8 +5B3E37E8 +5CDC346E +CAAFB037 +BF2135D8 +C6977D49 +8D61C84A +C6B1C620 +30AF013B +B98B3270 +CBBE51A9 +43E26F1 +99534D9A +11DEC7C2 +F3952B8C +52900E87 +80D2B350 +838A2A8C +F8BFC35A +AF0466F9 +CCFC01C9 +C4A559B8 +5FED8BFA +ECB87D1F +7BF187 +4662AA70 +1274E59B +41188FCB +A769BABA +38F43333 +D4645494 +3E464034 +6F3BBB27 +8149A2D5 +D3D96C7F +C04CB115 +DE3B6C40 +B94FC85F +E0E6291E +3E22885A +30D35E07 +81014DDD +A40ED586 +A713CBC9 +7E0CC084 +439FE695 +F4094931 +C293453E +741A83B0 +D9C2E5F3 +4E623673 +309436D5 +807620F7 +7DE3993B +8F31B5E7 +F12F65FD +66763A72 +D3606695 +ED7794EC +8BD7EF5B +5B3449BB +D9B93EBC +5CF89E53 +103CE7A +A1ADA14F +BD020E01 +F737C35B +8695E1B +2AAC416C +43B6BBD5 +31036C5F +E5A61222 +F3E01282 +9A93EECB +BA874043 +1D010D4C +3F45AF54 +662F04F8 +279C9BE3 +217787A0 +1D399000 +6669B218 +A8F4D699 +181ED599 +A584DCDF +97A49036 +C5D4A8F7 +3C7351B3 +E4A7A0A2 +9A13953B +A9649AB5 +E9B91DF8 +CA6E2F04 +F0B63E4F +C0F55BF2 +38EBAE63 +8D8A619A +1A798058 +E5C218FF +8B67C799 +A81704DD +2562EF33 +74B37ACB +B2C84D35 +2E0EC87 +5CAC361D +7FA10429 +DDC1672C +3574275D +A831D84E +65339BB4 +4B936FAF +8348EDC1 +B1802336 +601EDB14 +BB5E4EC +48CE4DD2 +4CC93BBC +E77987CA +6348CFF9 +90830A68 +1BF0414 +C2BC8AF9 +3EDED4A4 +66B38B85 +CD6A6E08 +92B71F79 +6BB2BA9D +B4EAF374 +5B723892 +C350B751 +D7A56661 +576B1A79 +C66D8E1D +442DA54F +ED0C819A +809EBE76 +413B884A +817EF987 +D76CDB84 +90F40F80 +2BEB3E69 +C2782488 +F07FF38C +93AD0DA3 +C3E8DFD3 +5B804608 +9CEFF79A +BC524335 +495E18F4 +7FEB37D1 +A8F15A96 +3AE50033 +9DC5D0BC +D4A241D8 +8F3CC38A +4573A224 +5A3DA58B +B446C862 +69EFCA93 +83B911B +CD50A370 +2E05D74A +407D2B79 +AD108E34 +95EA144B +EA3DE818 +7AF026A3 +21366692 +4D5B7972 +C7D14546 +B6EF2543 +48E7457F +6947E018 +F6B2DD01 +9FF698B9 +EA11BADF +741FB523 +70901C0E +6A71C468 +8BD95624 +1D98077E +EF7CE480 +21F44B08 +563A0A30 +D9165A +7F8E8474 +219FFBE2 +FE1D6D6E +F7B8D66C +CA49F15D +C481484B +85D5310D +3FF17830 +8F69C740 +590A3DE5 +867A85CD +21C9758 +2E625FDE +7CD5B8DA +8BF43699 +AA17B723 +C0DBB2D3 +617F6819 +4D6BE357 +A2D89B90 +C4B19255 +748BC770 +4BA5F90C +2AB43820 +CB75746F +FE7480E4 +239B7D6 +2567653F +7BD1399F +55A842E4 +572D6A8D +CD1600C +6C880525 +1C18F7EC +C9C74D53 +AB3AB21E +F5EA5F69 +F6F730D5 +FA454FEB +978E940C +64D4DE80 +2BB0D31F +10268273 +D060E295 +85A74B89 +A7A3AE03 +7B8883FC +D0615497 +9D637210 +105C40E7 +F9FB184B +B4E67A79 +373530B8 +30E04C2 +47A1D75 +A6A67936 +1B789F9D +AAC21CCB +E00A8B8 +517BDE82 +B1004DA3 +3F745A4A +8FD0E21A +529E48CB +BE6AE2A5 +DFD7DE91 +145FF288 +2B1AD7B5 +C2AE7259 +88B84292 +373D8796 +5E4B4FC5 +971622EA +3C6F40B5 +5FBCF21A +144B7DE0 +C588DF6D +804B7F0E +4B6714FC +C1C2E61 +1CB08E0B +6355112C +1912B0BF +22263C9C +954A5DE3 +4520505E +459D0661 +70FF554F +F1FED0C0 +D1F602A5 +AE5D07A5 +B86AAF05 +452536BA +B00C120F +1431099A +42F0959A +FF1EAB1E +9FD43C93 +5076B428 +ACB3DAA +5D0BA50 +16E00180 +90E21E72 +D497B8D8 +8414A6CD +B933AC93 +18B2DC20 +5BCC1468 +101CA9C +5AF125FB +E65A4FBE +A5B927FC +A8163208 +CBC14C7C +A00E7C50 +62DDE328 +3704BAEC +B354A1A8 +1FEFA49E +BFA928AF +73EBAEEF +F21664AB +B82DC773 +397C3EC7 +6DF7A081 +7B57E52F +43B47A0D +4BB8B26E +748CD62D +1D057255 +3A01A19E +ED35DB9E +B9192006 +9DAAEE03 +6F88BC5B +41F22AAE +DAF9FD8B +8A8D06B2 +99E4A71A +E0E5802 +AF2050EE +35D07382 +3CDB4F32 +1587CDF9 +29E0BC17 +F6641B4C +35557A67 +20B08FD9 +F89BE3B8 +994D534E +5084DC42 +B49E2B0B +25AD0456 +B05DABB3 +102657BF +FA7342E8 +508B7BD7 +FED0EFE6 +5EFAD4C0 +15101C27 +420BBBF4 +1783F9D0 +CA890820 +BD3539D3 +578ED490 +1DA8E967 +134F8B74 +D6C5A224 +8C8B1F06 +8977D881 +541937F5 +9013604E +4B54F163 +A9030FBF +A9EF1A9C +CB29FA97 +94A3F001 +4069BD15 +C0D5E43E +4E17F81E +90FFEC8B +32D0B0C7 +4044EC4C +7D7935C3 +BCFF474A +9AD1BF76 +2ED2D299 +263F8852 +4073932E +BEDCC036 +7A548119 +ADF45572 +7D8C451E +465569B8 +CA9E87A4 +731803CD +1DB59C5C +A90C6543 +A22221B0 +173A0706 +E040DBBC +941E546B +5503B9D7 +CC5D8948 +F7FE8FB5 +1AA3AAD0 +20229A2A +82CC4C33 +746BC086 +E9F90D08 +2B356E1A +14897456 +D9BC34FB +9056CB82 +1DD450BD +BF64BC9A +166164AD +94363CB2 +ED715F84 +CF4D9ACB +BC0EA0A1 +46E9697E +72428536 +D9569B91 +2B84C8EA +D4CDE0CD +E439EA2C +E19B71D5 +E45E8566 +541A4655 +845B296B +B2E478AE +1A35840C +C94F4E9F +A7AB9164 +AAF8D027 +82252CBF +20106216 +ACC1C08E +57E445D9 +FF68B8B3 +4DAE2000 +B5A7ACEC +1E9BE78A +88DC5BAF +C8A00837 +210B7F85 +E2A072CF +144DA567 +C6467799 +4BC0A056 +C60819E3 +B2B1ED7C +C0ADC696 +56F0E8AB +8D538C1E +879C3079 +6EE2F434 +7B9CD649 +94A30F21 +7DA211F1 +64035D90 +916A9128 +EC9C52F6 +92991BB2 +53F4309A +5AA71420 +F9B67D20 +45706BC1 +E71E83B +B091D34C +BE56577B +7D3CE09C +1A3F1DD2 +F90362F3 +3FD83E38 +E8274EA1 +CDFDF1C2 +62FD4CFB +C3A1DB75 +15E3C709 +B7F81AF6 +E58D41BC +5376E522 +698DCBFB +C76EBF96 +46682F6B +E5C0AE29 +50259284 +91A4E263 +4B03C104 +4B04D974 +914FF9B5 +783CEFF4 +4B232A85 +303E2F77 +6E902ACB +8D630D23 +9BE394EC +461237B1 +22760BF9 +B1F5BDC8 +F8557002 +9CA2BA41 +76418996 +B734B9D6 +C5D4B1EB +59F49A63 +4F9C6BB0 +219811DD +CB536800 +BDAC548A +824F1A42 +5CE7C68B +AC7A5DE8 +86D89A36 +49E127B3 +EE0E8BFB +4997152C +A43493BE +ED7179 +1049E699 +431EBDAC +379BEDAE +FBFB2AF6 +72C255F +F37B5D5C +2D15F748 +7759FCC8 +D6730ACA +52AE1913 +D709F4AA +581518C7 +BE85DA4D +1A24C4D7 +50ABC4ED +7B50804D +194F2CD7 +A56680A8 +1520F41A +A614FFCF +5F66A0AA +46877891 +4926E937 +74E93C8E +62515A1D +8F3F6DF7 +AA4D19C5 +8057E286 +8C90FAB5 +4AD3F2DF +D953B36F +37D20E08 +644A2AFC +5CF19FD +8C9431A7 +EEDC46C5 +F86BE6DC +6C12ED6C +5EDE86A5 +7E59C795 +5EB83E6 +6F36E55D +D9E35BDF +CC7E1D72 +21A42C4F +332994C1 +4E460BAE +C9A0955F +C080A0A0 +B2013D50 +E6CB68DE +E9C759D0 +4A1C7783 +D1028E6C +CEAC9773 +189398E7 +B57C20FE +D0D3E05C +6FEC2AAD +17643391 +1291E620 +978A16DB +37BE98F1 +9F773872 +1BEB32F2 +CF3DA84 +3088C11B +2BEB338A +1F308D75 +DD542BFE +C568D953 +BEFE8926 +B9E201D5 +EE6FA353 +826FBE38 +CC867513 +A00D32D6 +CE9B8989 +8D3CA53C +1718DB6C +CE2AABE9 +8FF0C7CD +DBEC0AA6 +E75EC71F +FF266269 +3D7D0B68 +D606EE1E +56F86B85 +6B67916A +B164B35A +D4E7337D +D7A68BBA +A39300CF +D7C72CA5 +A32F6380 +385F8023 +1FF83E95 +F4E55989 +6BED2F68 +C714269C +4D2E9366 +8C1A2FE6 +84756541 +6D353F18 +741B7419 +3BE84DCE +8FFA851F +FCA5E50F +519AC53 +2E36273C +995F9DF1 +A1A165BC +F5E804CE +DD395EDB +7B2D8A34 +FC3F84B1 +19EE5FEA +EB2CA6C2 +866CE073 +B60059C0 +35395446 +BD2B582E +C6E73349 +634D409 +B9AAD6A6 +81B516BC +6933344A +806F4464 +22AA3AB2 +A6FA442A +31DB2D66 +F64AFBC0 +480C5B8F +8CE98937 +F8BF9101 +395669D0 +A560F096 +C8A13D26 +9C62AC71 +C0EA2E1 +BDC5E76D +51C79BBC +E84416E5 +30CF1A91 +E87F3E55 +6CA51768 +4D09690F +D488F996 +ED850E82 +510DA36B +709F9D1 +A6AAD3D4 +E0C4B7BB +1A581776 +2F11B35C +748C7EFD +A2F0722A +A8C6D678 +915B88D8 +42E5FD90 +25B58AA4 +8FF166C2 +B5FC3947 +6427FBD0 +E1C01EC7 +91FD1568 +FE570CB2 +BBEE870B +811FA63F +BE89954D +C83ADB4F +C1B4D237 +65AC0055 +5E2B279A +3FC59820 +B1634DAF +AC02E4BB +B9D8412B +AB22C318 +9E528E95 +F4220FD4 +D83A7E2F +7C013BBC +23849524 +BEED0AF2 +C9AD6213 +4F367F0B +8FBA0438 +EC5899D7 +A4111441 +2D18DAF5 +E7349E7E +57AC8D6A +A27E98E3 +AA1A992A +5E7E0E0E +AE4AF437 +20A80262 +AE20A4C +2CA493A5 +FFC756B3 +68045EAC +A56BE46A +7B3EDB89 +BF17C1AB +445B3851 +FE16BE78 +23D0640A +694D05D9 +D76F0407 +AAC3808D +8D2609FF +BDBECF1E +D6074958 +7EA401E2 +CAD394F3 +4A67FBFE +A2A7FBED +59E0B573 +CEFE2B20 +2BE6EB1 +85FF9E57 +42C7617D +E9E01845 +43F02D16 +DF309F8A +880350B7 +65CE706E +CA6A2B8C +5C38AA9 +6C60FA8 +42BAB35F +9453366B +D5864332 +A25A3164 +F32EDF79 +C757635D +F6712B29 +4C43A3E0 +80D02D7C +A9DB16CA +55270F91 +3FE8F468 +AB0C835E +DD8A2F64 +D9551C26 +4642684D +69D1935E +9A7A2413 +E0BEC20B +14724D4 +B4A43613 +559418E +1E4A709B +A32F1E7E +EFEFB7A4 +5B26F487 +E6CBF46D +7139D0C0 +EC214DFF +7045BA9D +A9AB902A +CAE7661B +3B50F210 +A065F80E +B353DA84 +E6538D1B +965D76CE +E7F01488 +A1E57BCD +76920B33 +4EC379D2 +43909492 +8F621446 +C9033570 +FEEEB7B8 +E6FFA222 +E8CDDAA2 +3C5C0252 +A63AF91A +D545D3D7 +28ABECA4 +EA14F18F +23FF43B0 +F9F0198 +24568599 +71F0C3DD +63975EB3 +BF3AF93A +7B95B627 +9B0D74D5 +20967FF3 +A621FE0C +6CFF968B +909CF3B8 +79B5DFFF +FC87A4BC +5BB19840 +DB7D8F85 +D4641400 +54449140 +CA93FF98 +85668EF3 +C871B119 +58D44D70 +D93434A8 +453FD827 +906A01B7 +FD446B38 +CB63F172 +E4B0DFD8 +D4FE1E63 +C78583A2 +1D7463DC +7D69FEE0 +93EECB26 +337FCA9A +5D5D7447 +1ACDDE16 +C4CB8D59 +F178B39F +292E3426 +7A1A4318 +DCCE0A6D +EEC1FCB9 +3B264208 +F9D7CB6 +9A23DA53 +58B2B3A4 +654072EB +6CA920C5 +E145E547 +F5FF4A8E +AB7C553C +2A84E62D +6F6AE7B2 +322DB9DE +17E670D3 +7BDFB473 +7CD05987 +5B12A205 +5E9FB325 +542A1478 +FF46384C +69DE91C9 +65B4C13E +78DA8BBF +D85BC864 +3882BAC6 +444A8F13 +886DBD37 +2613D1CA +7CF2397E +513D4563 +1C57D4F0 +32B75B54 +E18B4953 +B59C2B91 +98F11972 +594CCC07 +39BE7B96 +B14E5D15 +ED093697 +953DA37C +6FDD4B93 +8D678AE0 +8B149A9C +B9ED6AC +E4FE210B +44EB15E9 +805CE5D6 +62FF689B +E6C011C6 +42C85768 +EC22FC81 +16858F65 +6A6BC5F1 +E5090FDE +482D0881 +65EAB7D8 +620494B9 +6160FAE2 +542E102 +81BCAF6F +C31AABA5 +BEFFEDB4 +A802765 +68A8ED5B +A47FADCE +3EC1897A +4DBCCC04 +83EAFD50 +6B8E05E7 +4FA1891A +9C2FCD23 +9ED7C877 +15FF9D1F +67DE6F18 +D2932D4B +E4B31601 +60B47713 +C1326724 +1F5FD6C9 +2A54C06B +599854F5 +C2121D8C +2D0FAD3B +762DB289 +CCE2E11E +622AD608 +29836424 +C9F1F838 +4E0F9445 +16C53328 +B9F2FC2E +28FFB831 +7C216796 +E065DC2C +561328B +92EEB73E +BBC5AE83 +2DE49E4B +BB32B7FC +E59D7B63 +B3375867 +5523615E +5532A7B5 +6890882D +21F33D70 +EA855CD7 +CBB7B3A1 +DD9C122E +5CEAC143 +E9E4332A +6F658BF6 +57E90D54 +715AA7A1 +DE7768FF +D8A3302B +1BECD73C +AD442F70 +EBBCB63 +5D25E0FB +EF9854C7 +DEBB6E96 +61591E99 +BE06EE6B +F74EDD0E +124B1712 +45833671 +1227307A +546B647C +9D2398D1 +DDB609E +EB68EAF7 +F05AFA0B +A6EABBB9 +60B5FC76 +992D25CF +A99743C +5FF72996 +E3D84005 +F47AC3D6 +D92BCBEB +3AD6BC2D +399AE49E +FFD7134A +80856732 +8C92A116 +D23F2A7F +1C1FF7CD +7E97215D +63CE5EAB +1E3D6441 +8CC7E1E2 +3144CABE +1B369565 +E681B9FD +3F72A224 +3146105D +68639F13 +61E4A798 +CF28AF43 +F18B6903 +F4D16333 +557BEB41 +F5DEEE8E +41F036AB +D0DBBD23 +E8E240CB +8FE50644 +8EF8CB38 +F8D6EBA6 +580EDAAC +25F0FEBF +1E09176D +CD156787 +8198153A +3D5D3DE3 +5132C51F +4B39B7FD +15BAA338 +AC2E0CAE +91DC2332 +3632CBA5 +2AD744AC +EF31B613 +6A9D8019 +17DE8C90 +E5CC66F7 +E81411C2 +C5B6931B +E8CF72F1 +ABF2E66 +5B7DEA27 +340E7880 +2B4ED84D +F6E86748 +9C181F92 +55DCA269 +1CEE9C9D +1DB0A271 +B1BB73B1 +2B802754 +596ED430 +25F4A422 +E186EA6C +A0793E1F +B54A8F34 +4EEA557C +A8085CD6 +276D7E7A +F711A6D4 +2534D88B +FA8CEFBD +A7E9E1C7 +EF6F2E +4620FD63 +7955C107 +50E0A968 +81DBA8B6 +92E0F3D4 +C78C01F7 +CFE5AB0F +C290FC3B +F12CC1D9 +56A9B1DA +69AC05FF +964D8EE +EB198C02 +A3D9435 +30D0BD52 +2A1A5868 +DF336813 +14C97AB3 +BA6717D1 +43FC05DC +32A6FFBC +C47276AB +DECB3B2F +1511FAA2 +155693C7 +E5BB37E4 +CB20ED97 +FDFD4014 +FFB25A3D +4F8B2CCE +8EC8D538 +A60DDEE4 +9E6196D0 +8895A4D +A2528B98 +D02F59B9 +47662556 +4FAB84CE +6C7FC2FC +F351CBF4 +F1917707 +B1F2737C +B46CC768 +F87757B9 +A24CA3F5 +74EC8337 +C46290C3 +77BBC380 +1B3087DC +C816F73C +6E2C562B +27C3E900 +4FB423EC +A77B1E37 +51063C80 +432108D2 +11F0367D +1D08F91D +D56068FA +F259DE46 +26CF3619 +6E6AF5EC +10AFB2EE +14F925E9 +5382204 +9F482CE6 +90B0897C +C768AA0B +654ED88C +AD60966B +8EB54FB3 +26275630 +A1C50A7E +21587F6E +9496FD06 +4B768A3F +1798404A +28C6B4D8 +5B579E3D +C79ECD09 +EC63FA6A +162A0135 +7FB7DDB1 +A0167E99 +196F14DB +CCD227F3 +3FB917CC +A3D30D38 +71874379 +E9E489BD +5DA989C2 +4F7C8E1 +F6E0502F +F8445D16 +25CC5FFA +FB06FF63 +CFEA3C99 +E41A8123 +6A5A256C +D7B67156 +50BDCCD2 +8165541 +F067F327 +B1E17258 +6901F3B0 +8B8CA0AC +CBA88A2D +4736E05D +DD5AD020 +35B501DF +73C67F6F +F2C513F +E6CF7C2D +E6A85B1B +8AE4F7E6 +1ACA7CFC +BCFCC182 +2930369B +642DC973 +990B6772 +681EC185 +164AC235 +9C676AC8 +B200AD7D +F13B8C8D +9D22DB12 +CE95663D +CE956E42 +29485F4F +BC5D5F8E +DAB561EF +C4C15BAA +77B9192C +86E8BF86 +5933ECE +E50B93C6 +F8B0CFB0 +3286711B +DD558ED9 +DD043899 +4AFAB231 +637BB2D7 +87036D19 +9A30430F +27798B63 +4D6E407D +CEE251F5 +ADFFB995 +B5C885B2 +7DF6519C +6EF51C85 +B95DAF30 +65EA99E7 +772FBB19 +49DBE1EC +F386A79B +EECD2F55 +8935CCEC +BAC4C120 +C71F82EF +2DF7E67D +9BA39901 +9614A4E1 +C6304402 +236FC777 +D47A5719 +8098EC85 +799E34F4 +896EBD9 +BAB10372 +32ED359C +6F9F763B +9D517447 +22B55AB9 +8E6F4104 +15BEC5D3 +6252E010 +23B5E8E7 +D0B113BA +965C42E7 +F2A0C19A +24CB582E +1F449982 +2E805DF0 +851608AC +755273C7 +3529A161 +6395258D +C5BD7D0C +27BABE75 +E1628E4A +47E5CD77 +EE797B13 +AB11893E +2F65151B +9CE2B20B +233C28A5 +749A0C91 +846BC1E1 +8C36F8FE +1489CF6A +70FB6BE0 +D0A84133 +9734B9B7 +FF166A04 +D118033F +BDDB2D63 +6F6691F0 +44FB36D0 +EFF2B14E +AC02C863 +ADFD2972 +905F6E84 +7C0008A8 +4A043A53 +D104FDC0 +1687FF25 +E6CF8FCF +120143AE +53F92C72 +19E2E798 +EE8C6B94 +15CEA57D +C8968EBD +D50EFBA3 +A8EA5FE1 +E2D073FB +B4EE195F +8928A91F +6B9EB970 +C24B509C +5D340563 +85FC3F3B +934FA012 +A2AB8533 +A6BD3187 +105DF0E3 +243ADD05 +49C299EF +7A42F84C +C90A1935 +3268B298 +CFA3B2EE +470C6457 +E579D2C4 +BB10428B +78D10FE4 +11F21813 +8424CE28 +EA2B114 +8239463D +9804414B +44B4FD1D +82D50F88 +10AED1B6 +E4768ADE +E7235A66 +C8705714 +936532B0 +15C63108 +92A91B17 +154B2415 +9BF0D15C +5F451388 +1DC102A8 +96CAFC23 +B076C0DE +3EBDCC3D +6B2EE523 +C6777AA9 +F7F48C4A +B1E8ADBD +FA30AC90 +5173D22A +D22827A6 +6504AED6 +3115E6F6 +E8937768 +C5ACC0E9 +366E15FD +AB81C84C +C27AFE96 +7361C8B1 +613A0811 +595F48E4 +1619DFA6 +233D2474 +4C174E1C +E7DCC63F +308FDED9 +502A0AB0 +C5004E90 +B7FBEFEB +918A77FF +F7235A04 +5CCB8B7E +3BA4B1ED +32F47DAC +FF7348B1 +996C8E7 +7203F1B0 +70583A2C +4D8046A0 +551119AD +BE5B31AE +35400CC7 +E8ECD409 +D1C104E0 +1A0858F +F26946 +458C8B3F +E8D66E91 +2F3F6384 +B36EC71B +289CD4C6 +6CA9E35 +B198A8B +816873F1 +346D66C9 +BD906E97 +802E5969 +261BBBD1 +9D7605C6 +72C2CDE6 +6C8DBDB5 +D7C8DD7C +F43FB2C8 +A9F384E6 +78FDC918 +6D20841A +20755F34 +F4C6AF99 +19393B53 +A525AE84 +CE881A38 +3D075300 +9B0E4DCA +7EB7E7A1 +4C4FD44A +78483ED6 +32D9D894 +1CCD379A +EA5FEB4B +F7E001D +44FA69A5 +E99F66B6 +9E16CD0B +CD098C41 +6DAAD279 +5FE50411 +CC855E2 +130C6563 +356CD9A1 +BFB318B8 +2E963C0F +DC5A046A +FE16FB +A599857C +F72FE561 +2914E4FE +B247AE8D +6A6F13C0 +B1052C98 +8086E53A +845345BA +D43D5F7A +82B30F5E +4206EB1B +89CCA1AE +86289F6 +567F22DE +25624C58 +6A78EC3F +7EC32D03 +8017213D +3A141336 +D1CA4E6E +FA84C2C +FE670E0 +3238E01 +18DF1794 +A7B900AD +1FCE47CD +14EFDCB1 +C21B04A8 +4C3343A2 +E5E611B7 +ADD06EF0 +32C81695 +201A9FEE +BA8925BB +5182EEED +7DA4917E +CC331235 +C304ABE9 +C2A16075 +937E1C4C +CCA0184E +9DB6C45A +3F2A79C9 +151B469E +162F22DA +D955D54E +E857CC0E +FFF2005B +60AD87FD +85512214 +E0A506A0 +FAF1A145 +9DA17F03 +332D26D1 +9EDF9643 +7BBF2D9D +3414FEA0 +A8FE5964 +D4841879 +3AE4E5EA +BC6B6D60 +950F4693 +70FD0254 +177C7A1F +635FE5B9 +C0C5B6CD +15D1D22F +BA495903 +CC100F38 +A5F1E225 +5AB4584F +AC4731FD +ABB04167 +A0E153B4 +5982BDA9 +8E2EE3AF +D635C631 +7C6154A2 +9F0EEFEE +429B22CA +B1346D4E +6B21663D +6A7EDD8A +DA34A355 +217132F0 +683BA78 +9CD46320 +A5D3BC4F +3194AB03 +DD66F958 +E7506C47 +17EE83A2 +4E4D80A0 +EB56662F +BE889C58 +6F5F6745 +2A05C12F +13D266A0 +3B2B18C9 +EF435E02 +5604DB7F +D35888A2 +CCC34421 +55E24355 +7F607F34 +E493720B +C6A492D7 +7DC6A789 +E01474B2 +97D35C32 +71F32335 +D3083D7 +2327D424 +35EA4BA1 +F5B20C6F +3ED28FCC +453A76AE +192A79A6 +2E64285D +A9463AEB +374E22E0 +92A5CF8F +E707F8E8 +B8E2FF36 +E8E959EC +91D9796C +F03960F6 +B62467FA +8836A487 +6418A93F +60932160 +3B72687C +37BBD7CB +1001C76F +201999EE +5955A1CA +925351D4 +767540E3 +570BBF27 +A073D4D8 +FE96246A +44784995 +232C0150 +AB7BCE2 +D47BF099 +BFA6A422 +70F4BC01 +C2139449 +F9ACB817 +26657111 +13263449 +7989D26A +2E972B3D +2F1C1C6 +930E479 +23243FE7 +BA7DDF9C +50C8AB43 +952377D6 +4C6C2B3A +BDAF48F3 +1C0BAE6E +7F6A8C04 +F529B9FA +9ECA4162 +342E6562 +9BD5EB52 +A14DB3C9 +14B1DC2 +4E1BB6D1 +9A1158D5 +73F84EC +685BD9F5 +8CE72161 +5F116605 +BA861D43 +A7150AC2 +391A105B +C8D798E8 +16633750 +33B29C4C +54211362 +34C2D5FB +CA197734 +A635990A +4E606FD7 +9D56673B +89976DD5 +5F2D2794 +81E95955 +9377829 +5DED53B7 +FEAD5592 +1CC6419B +BD3A45C6 +65FACDCA +7EAD0EF3 +EB856702 +D857FA75 +3B92DC0D +E66AE58C +51912618 +C63C75BC +ED05B556 +17EC2B32 +9F692578 +C706059B +D88D5576 +C2661C7B +6D7751C2 +119292CE +418700CA +2A2BC3D8 +CA20D341 +8A8F325D +D4A2DC8D +959FD62 +67883F8E +FBD3686B +6B862363 +F8C13880 +FCACA893 +8215D90C +67567E2D +3B501BED +7AFBFAF4 +2EC3CC34 +B360BFD9 +716C5E9A +907B1432 +E253CBD1 +4DB52F87 +6A37A21F +C860A6A2 +72DFE5D2 +84E0705D +80DDC195 +1ECD4E92 +2D2035A1 +B10A5B53 +C9AA9A79 +E999CC8D +C8C790EB +F7629DFA +93158872 +FAB6E7DF +58A0A3D +6104EAC7 +2BACDD14 +A8E3DE88 +AC4E16F4 +F7042189 +5AA6D923 +F491667D +C769767B +46EE7E69 +CE4BAE4E +FA1BE581 +2BF14278 +5356E813 +6225B503 +D33A6F26 +1A629247 +BD844A35 +E33ADFB +EFE720D6 +3D49752E +AD542CEB +EE36C608 +99FD833C +BA893EF7 +47E4A8A9 +B269C1DC +CEF39BB2 +91FD5B03 +C02E6C1D +29A3817F +70894875 +8C851D1B +8446E920 +8CBAB8AE +D9D7B185 +97987DFC +ADE83493 +4CD1FC4F +1D82738C +27665936 +CE3C907 +990136FD +E1E40CF2 +A3E15CA6 +DB7D4E0F +D8E87ED +FC23DA2F +76A6A0C0 +1C7F403F +380BCEC9 +C2BDE917 +74145443 +14C0823C +8D73C415 +BD7B9DB4 +C83449E7 +364D21C7 +7F01C97E +9ED9F208 +51417FC4 +D557CFF2 +5ED6B81F +BC0EBF41 +608D56CA +60AA90AF +8FC8A8D6 +809BE4D9 +47CD9035 +8CE71201 +B442C067 +A380EF4D +7B74A914 +513ADF78 +63E5C752 +6D4F2B4B +82717D99 +EC19F48C +7D0D1EC5 +944D936F +358B8D1F +D3A7E17D +5E6DFD92 +D6D2B538 +133AC914 +22C4BFCB +A9F4ABBF +7DDED93D +6836C5 +3F10AEBF +71713080 +A1868A02 +EC341DE1 +33D409F1 +41EA5D35 +47F18F89 +7C062A2E +1C66DC90 +D5E11362 +FACCDD77 +D96EA1F2 +31676D3 +B00B9D1D +36F80278 +754F427 +3D8C40A3 +D1FB426C +ED4869D3 +AD137726 +9704A7D6 +107A0E2D +AAD92A50 +58019B5B +F6FD55A +E876FBF7 +13451AEB +A530BF41 +11FCB24D +EF5D7F1B +BB65E3F3 +DCAF1904 +4262AE51 +8C2318E1 +96E7A13F +DDA281E3 +7B44E7BF +8048EB55 +AFC8D749 +D3F7E592 +23FF8DE +105E2923 +969758CE +B1BF840D +D301EDDB +42A3C6C4 +2C934ECA +B2FB9ACA +452302A4 +C96F49CB +D7342392 +48A6D82C +6B831657 +1A6989B2 +312D282B +9AC1D170 +3FB3070C +D83B178C +D894496D +5FFA91E8 +436E970D +54DC6812 +8CCA890F +96971388 +9CED7192 +216196F +BDBF8734 +441B7DC6 +8FCB2D4 +1C3375E3 +19EE1338 +E8BD4F25 +D65CD246 +85157D36 +34A4CE5A +BFF7BCD5 +41DD5123 +D92D0021 +C0265B3 +652BE05B +7B31FC27 +E8BBC732 +E5DB7686 +2D1EAFF8 +2283884 +CE0E4257 +1936BB27 +6ED44FBF +476ED2B +C249E9F6 +21C0827C +8DA28ECA +707E075B +10EFDAF6 +3DF4B474 +24AC5C3B +81F8A453 +8E1AF272 +E69E1816 +C40F1B4 +5AF2AD1A +C1236EE6 +78507240 +588C4851 +385396C3 +BE2210DE +E8FC3FE2 +B9E7C8F8 +A33939 +B9E8F7DB +F7DF1BA4 +400E6C2F +1139C2B3 +8195BA65 +A6052E5F +29E1F01D +512ABDD6 +ABE172A9 +350BB8FB +63D89399 +6C7CDD2F +F6E20A15 +36947843 +7D26A79A +133DF31B +AB375C67 +35D4F0E9 +8060F5A6 +94893A4F +1B4E1612 +431938A9 +F4F22D48 +E83BC91E +98D9DF02 +7CBB518A +947735EF +16DB6C38 +7BBEB95B +393A60CF +6984032C +F1879BA2 +F014440B +61CAEF50 +F9BAA90B +6D9CDB7A +4A4C3D3F +DD498DC8 +E27FE395 +AEA01257 +15FEAA99 +61A173A1 +28EFFD56 +A27152DF +10C613A7 +47AFE324 +5B4D4B5 +AF67027D +11ADBB9E +F8B22312 +4A9C0C1D +E94F39C8 +9AA4F0E2 +4C394A49 +41ABACE1 +6A96270B +171F3E81 +F29DB470 +A9E7F67E +6B445012 +B53EFB86 +B0AB92A +484432B2 +7C789E2 +116B012D +5A5434DA +83DD29B0 +418637F4 +C9E1FBB7 +FD84E0E9 +BB44A4ED +4847C699 +61807BB2 +F558A9F0 +264F9191 +697F6915 +EBC115CC +A1604C6E +9CD73651 +50ADAD72 +DE3698D8 +DAD728B2 +58F5527 +C58A4754 +C8CCF740 +A5CD4E0A +966E50B5 +6DEA9EAF +66DEDD5B +CE18EE1B +E0293294 +3C0C586C +ED04E099 +A1BB7722 +78AF5367 +3F0FBBB7 +4F623EEA +E3E1A85A +3C8EE1B0 +D2851D20 +F07248A0 +713EBA3 +8CCDC87C +B5ADE0C6 +54DC4354 +F7F43DE5 +AB512848 +69136DAC +71CEFCD8 +5F264F19 +D39D50DA +A184BC23 +57F38C31 +34DFEB30 +6B39F755 +60F7B6C8 +EA7FF406 +914CD331 +F4A15FC9 +68DB20A3 +6609D547 +18BD6EF6 +F5DDB763 +9E2C6236 +A9C0CD72 +EE8A864E +FA9A7891 +DCE7F5DE +4E5A9B63 +FBC574F8 +13C26C91 +70A2AD7F +9514018 +7786A6DF +708A442D +8AC98261 +57EC9F69 +D8B92F1F +5525E8BD +CFB927EB +47BA617A +4A71DA0F +9632F7DD +4A00D653 +3FC603A6 +A34C3C9F +EDFCB326 +BA31E996 +4158D5 +888F01B5 +F001473B +D67ACDF1 +587F7E20 +EC9AFA96 +6942D697 +76FEFEE9 +ED260881 +53D50BC9 +43FAA199 +DA4F8CB2 +D7FE8FC6 +7A659755 +394C88C8 +EFA3AFA +87710DA8 +DA1FF12A +C5D4E7F8 +4F0A47D7 +E7C2A799 +EE894D65 +20E4FD0E +8E51626 +17BB7611 +E48021B1 +4320CA45 +5315D225 +39684701 +3E943281 +B3B7B298 +A63E5C66 +11F2EAE5 +2E339781 +9BE79114 +187467D +9479787B +565D0658 +B43DBE73 +67F7EA80 +D1962413 +BF4B89AF +AC03F363 +1587941F +B7A14BD6 +AE1A36A4 +BF710690 +8009F7B0 +FB37D608 +58934215 +327E7B3E +A2BCED7 +57DB9C90 +3E7E56C9 +E554BE2A +6B6273A0 +766F5A68 +503BD141 +586BF1E1 +AF75978E +D93FB741 +75268390 +BDEAB299 +9871DD6A +9C042A7A +4CED46AC +706B559E +9C9CE827 +EFDAEFCB +A1AA3846 +330AAB65 +602F6FCE +DF14BBD9 +8BEF0FE8 +CEC4AC8B +28456573 +95AB0149 +43E11079 +B50D7970 +6F8F89C6 +B96DCC6C +E114C8BD +CF3F36AA +E02901C9 +8B452A2 +8AFEE7A2 +FD7C3D61 +4DA46DA5 +BD5C204A +83FB677D +42615EE0 +3783255C +9FA48033 +270F0FCB +157E94E0 +CC89D359 +715FCAEC +32EF8DFD +829D0BCF +E4FC364E +A629CB9D +7CE1FED6 +D6E9FEEA +24E55CE7 +8BB2DA23 +2FAEBFC0 +AD6EF205 +96142124 +6891653D +C5061A39 +9EA7F89C +D2CA9BBF +544A569 +E908D41E +EAA11FBF +4250EAF7 +6A5E60CF +5F84A53D +4324D154 +57320611 +DC3C692F +24685A97 +40F011E3 +25A224E +3712F01 +30F1AB94 +45F92B8A +450F8D4E +F3EFF92B +EA54D0BB +7E10A58D +D51BDF85 +FA6E7358 +A16E06FB +CA158DFF +9AAFDAD5 +AA48F649 +A4A78E50 +F2F73CFA +519FA6F5 +32933CF5 +9E55F1C2 +806019A2 +E56E0B7E +5F598AA3 +564C6D40 +757BDE5D +30757BFF +B906BD37 +52C6C503 +D2B00C73 +5969C7A1 +84FF193D +E668D8D1 +71E66078 +A200D7C6 +6585828A +FF8864E8 +B9EED36 +12C9F3AB +2F2C4A2D +2998FE0A +A1D47491 +59463A75 +1347C537 +77000037 +E6AC6FFE +C74CADE7 +83B75335 +767A69EF +4248CAAE +1DAA4A34 +BBCDEA3E +CE177B23 +59449B11 +A9DC563D +85589ACB +8926A959 +CADAB503 +6A1E5AD1 +E79EAAB5 +9C25D798 +B4750BE3 +249329AF +724F7831 +F4D2E094 +CD605F43 +CCC933E3 +4231A56 +8D15BB64 +A7B1E394 +FF2B04CB +7260C6F0 +A483E58C +35E5FBAC +A3D734E9 +64BF02D7 +24F8B625 +FBDA78F6 +6FA335D5 +5CAAE8EA +EBE22B69 +9BE5C3B2 +81028FF8 +E20FD2C2 +CC8506BD +E079C912 +BDE0AE94 +AA4AD182 +AE682162 +AADAA077 +C757CE81 +E4BBF694 +8ACFF53D +D1E85D5E +E29E9979 +9DC46E06 +A8FB412B +CA71D109 +987A6F6D +E5A13D87 +BCF3C6D6 +DA5A6320 +E78095AF +C0C4710D +7F06A362 +FF3D8A8F +428A02D8 +2EBFAF55 +D25B93D4 +344E75CC +ABC855A9 +E3577D95 +843C4274 +F5326A2D +EC6EB288 +7C4C82E6 +A70953D8 +8D8B314 +8772F0BB +3BA5025 +1BE5CFF +9592B505 +B9FE16F1 +EF77DAF1 +4C7B4119 +8B8FEB44 +3542576F +375EBF3E +D0927BE5 +2C6A3AAE +45D18D70 +6126FAB3 +58146389 +FBF50CF3 +3129860E +4B721C54 +95BCFF3C +DDF12106 +1E2428D3 +827395A7 +35266B84 +3CC089A3 +B8198C2A +B8EBD35B +7EBB213B +A93DCCAE +CBB25C42 +2A03D874 +46F6CAA +82986B02 +47EA89A6 +2C3E7BDC +852B0630 +A928EB9 +66A2BC66 +BBB43A54 +A6F55CB7 +FE990460 +5FA8BA0E +1CD34B74 +1C0F2BE4 +FE6C53A3 +C325B6C1 +A980B3D1 +9F031392 +31E17C1B +38B6D6A3 +E30D49E5 +E83F8C4F +BCF13E0E +28124F6E +57AF5DDB +691BCC17 +BD071C94 +DF4984C2 +8579EA0F +92150479 +7BB67579 +58D6EB84 +97754D0C +F569F71B +9990D0B5 +56DAB760 +9E988907 +9679988F +3EC5E4F4 +328D67D9 +317EB4E7 +5E6D7E6A +BFEE035F +D12E6060 +4F2A7A2D +F65F5B73 +54AE1242 +ADAD3A5B +61A81471 +FB09DC55 +72874DB5 +5302F1D1 +8B5F6A90 +82E98E7F +E808315D +DDF5B32F +C35356A6 +6F1FF7AC +1549941D +1460BF8A +D53684E0 +1A384C42 +D319924E +B0B1824A +2772DB36 +BA61B594 +712F9397 +41F5740B +C00A34B2 +F2FCE526 +4C874DC6 +FD5ED831 +301E874C +CE244111 +D6AEAE23 +516AF534 +FC101FD2 +EACEA514 +C23A0FCD +650BA0E6 +5C877E20 +ACB5DAE4 +5E56E78C +1AE6F2A +705046AF +7F53EEE7 +AAB30590 +2A1BD5B6 +300A6D8F +FECD64C6 +A8FF2EC9 +27B583C1 +29CAE718 +66D59871 +16E8C79F +14D20B3B +446862AA +1C5EBC93 +3831B437 +556E9FE +B877897C +D6FE7901 +D19ABB8C +964EB757 +D1DAC489 +B60AFF4D +31D01640 +A963359E +E233B856 +58D923CF +EF31455B +EC071BC8 +94F64E2E +F9384093 +36C8A1F +AC4A701F +657CD41F +731CAD58 +374B9753 +EC20E4D1 +E58959AF +E83E1021 +B7C14D53 +A651DDBA +D54BD80B +7291E323 +31310762 +A54A712F +482BD448 +1FC7B562 +EA69143D +4342848D +C4BB4C5F +B0B43A48 +962EF559 +5C395F65 +6C40A83D +AEC344E3 +881E5E3A +42D50FC5 +144B9CA5 +15DE8B4E +AB91DED2 +17FCB1B5 +87804536 +102205D0 +E57C9F29 +5D08E2E1 +A4AA0B4D +4FB1351D +F3BFE5C6 +5C439E04 +33A0A6AB +826A9A49 +D165E206 +229A4A83 +4897797B +396C7F04 +474B2792 +351AD33 +ECCFA3E6 +901B77BB +42B16DDA +FB3F707C +C6816341 +CE19D1AD +8297E119 +4458AB5 +FD9CA7B6 +250517BA +2E23BFF5 +F0D1C983 +699A7882 +557EB3B1 +D0D5822D +D1117539 +F271C507 +9364161D +6793E35B +8AF902C6 +DA5443B8 +EE1E1A0 +B941E448 +DE0E773A +4A41AF87 +D4AA88C2 +80B09F9E +53F2B381 +1C8EA42E +3D15C64F +93FE9251 +B242B629 +F7ED2942 +6AAE674C +EBF19F56 +E299D4A8 +4F22DB1F +20998388 +4742F182 +F6626B60 +992FB48A +26822FD4 +784D31DD +B84CAF35 +B8163E9E +2A27EE0C +FF09CF79 +81C74BBE +C914DAC2 +E768AAF6 +FFA5171 +CA93E6BF +E495891A +482A252B +18F8FD7D +DE52E34B +A4986019 +E363E1CB +EAF53373 +59FEDE9F +2FAEAEB6 +DCE56F6D +F10257B2 +7609DFE6 +4D0D263A +12696B9B +A56E0541 +8F12E1B7 +9E8E5761 +98C5816A +F2F8EFA5 +B91C1CF3 +59A19F9B +9235B967 +A58D23DB +71377517 +C50BCDB3 +60D31A7A +874811FA +58A69900 +CD8198EE +E4FA90EE +51352862 +3654B5D6 +B0442DA9 +5BA67D5E +A9B84B57 +FF61069A +21102ABD +8E6B59D +1DBF72C0 +9772AC77 +F26B2827 +E985C97D +CC311683 +E8216C66 +13E346BE +199D0C57 +578B8B90 +84462520 +7B33C9F9 +E18A5CC0 +8F70C75D +B9773D99 +8A8BDCAF +78B8631C +1AA0C9F2 +76FDD536 +8CECE336 +999E6F4F +29EB2768 +3417B854 +A56B87D4 +CA2F016B +69DED6A1 +8AF8128C +27732A2E +654939F8 +F0DE0291 +501F84CA +815055FE +99B595F6 +627F49E7 +2A7BE8CB +959032DB +7FD03C7E +54ADDCA0 +62EB2DA4 +6E458899 +2FE00E32 +B2E74808 +35803F87 +7369F52B +1586B4DD +61B61CC6 +1BDD1B8F +C6BAFAF5 +C4339DA2 +E1D3A0DC +8AD49CC3 +673B67FD +D81B434E +A41C5AA6 +BED70576 +22877C0D +71A3DC2A +FDE1F4AB +4FA1751E +DADBAFB0 +1C44975B +76EE876B +E3B81546 +86466730 +6A3F403E +255A72F8 +2D2AAE1D +77717644 +63E003E8 +40CDF1FA +FF37E1B5 +F0FC3CCA +45BE9807 +D8611D58 +D62AB82 +EE875225 +B8149434 +FFD0F0EB +2F3699E6 +7EBD4BFA +3E393CC6 +39777EAC +FE2A33EF +9AECBEB3 +322B14DC +DA2EB056 +1C942882 +C42C7C32 +A20E0D02 +E91D2834 +D465D9D1 +FC60192C +D3B7FCA1 +1E9B03FA +40323FF4 +DFA3D47B +2C26930E +391E6E18 +E340B164 +36FD76AB +204B0D9D +5F5027DD +FB05E9F +33C3443D +ABF1832A +152FEBC6 +FD83B071 +310222F3 +E07F3402 +61818FE6 +6E14F915 +F89FE609 +86FC4F17 +C860D97A +51B0EF08 +779B9BA3 +6D9C0908 +D14ED3D6 +692E8084 +233DEE29 +B85FF171 +12FAD29A +D37B7593 +AEDD969F +8E76CAF6 +A7FDDB58 +B5B7DFEF +A8881968 +50D65153 +D57A8EEC +7D144C49 +99B10DC +5660CCA2 +C02A1001 +7EE499CE +8C281511 +8B43EDB4 +31E58C4 +E9EAB787 +48BD8C20 +87C33E72 +9FD28F45 +9D8374B3 +3AEBB8FE +D25F7E5E +65B705F8 +ACB7BA8A +C7CE28F4 +1A365014 +12997929 +BAC3250 +3DA4DE9C +D90B5C3B +731BC23E +F952A129 +E5FECF74 +26D6A0 +B61C74A2 +B18937FA +E034B86 +6B3E73E1 +FC5891FE +E6F5F72B +BE380D96 +DB6DA2C1 +8BCAC0F9 +FCE57C36 +10230AAB +8E0B6278 +962C5A14 +4C257AA0 +95B50454 +478B67C6 +4BB1F24A +9DE453A7 +241965D7 +DE5E4EEB +77BCEB46 +A87FC004 +4EF35145 +35910ECD +8900342B +C9A653E2 +9AA2501F +DD4D16E8 +A2340ACF +F846821 +9A2A16D3 +33BF35C8 +185C4C5E +9A3A7865 +6CA5232C +8A93214E +8F9C13E3 +CF212018 +777D973A +3531924D +DAEBD9FA +4C4BA7D1 +C6DD4E96 +72F0CF35 +AD82F177 +B8486F78 +C89FE003 +991E4764 +F49CB023 +14C3A164 +B6B2733F +F78D6623 +F1C9D84E +6CE9487C +68F59E42 +B13A9862 +A60DF7FC +5680C3EE +8DBB03F3 +FE660987 +7F302425 +98915B +3EFAFEFE +819E3A26 +CF086D8 +EDDF6ADF +314D6342 +C7DC4A97 +231D9E12 +C8F0BB37 +E2A20026 +A9539B54 +E2047DA5 +3E5C9D4E +F91C18A5 +37B1EDB1 +DE88277F +765DEA9D +555D803F +6FAD1516 +41299623 +66D3E9F +B040E22F +28C55A65 +F5BBEB1 +8F85CC9 +C1F1FCFB +E0ACADA +FD138889 +F4E18B1B +6EAD0B49 +38441326 +17AEF5F +5A6EF970 +20ED5B3A +46A95C2B +CA7475C8 +8FA66C0 +3F831698 +E2C27DCC +7AB6C35D +9D979A50 +27F30FC +4FA19438 +321E637C +AD72B955 +C7BE128E +A428B5EC +48817E5 +7EBF668C +8DCEC036 +272C5582 +F8175767 +6ED7A880 +71E2497F +6EE3595D +D2579856 +15439021 +87C91FDA +A5682821 +E3FC8D77 +1545F959 +6341300 +D52520B7 +B0A0FAE6 +6F1C6BFB +226DE897 +4449D2DD +7E378981 +55A93F85 +91BFE157 +434EAE2F +AEC8DFBE +929F369C +DF654EA5 +CC2D5431 +152C1E93 +D800D93B +1969CB8D +46776BE7 +DF3D435C +2CD82C1F +241528BB +88B41461 +19463B47 +CD61AE6F +3C5DFE3 +8053B926 +5D0C9D00 +75240C8 +53A9DCF1 +B217E766 +616C0F89 +E73E36F5 +1E3E0BC3 +B6C474CC +9AFE8273 +AAA496CA +E9770A12 +9C3E2617 +3CB73C1B +2065FF5C +3A2B3E59 +280EF886 +B6A728CC +DDEE48DC +BE40F70 +449577CF +E5D72358 +5648EE48 +F6B9BB34 +F8E354C +84895AB6 +95DA9283 +882AF6A3 +4FBA089C +D27070D7 +17784421 +DDEBCE6E +4E6A43B3 +82AE90D7 +1A524C8F +D1C0C339 +993FA3FB +52CCA574 +523FF9E9 +764B2F69 +621F0749 +5C95BE3E +F2A36CAD +5C92ADE4 +F4238C46 +BDD0079D +CAE6D9F9 +5F3D1307 +9345998 +22C3C499 +631B8B0 +A6B9A88B +471749A7 +6BCD27C8 +5D371C05 +57081397 +F6CEF315 +1BACE19 +B7BF405 +5B6DD011 +BC74DA95 +781349E +F22A975C +72A5A101 +27BB6AED +933B9126 +14FBE3BB +50D095D9 +1CC937B1 +22CBC28 +1A6135EE +197E93EE +26A1CB1B +79BCF079 +A0134157 +9F232A75 +818BB26B +B2339659 +911E36A8 +AF2F9282 +347C34E8 +6255FF5B +1BB79854 +9A16AE8C +2A3D9B7D +93795FED +8284A6D4 +E58090F9 +A36C45A3 +F8065618 +4122FC06 +6F4DC90B +5336936D +F4E4BEDF +7A885091 +E19CB61D +9D398B7E +C9C4AF2D +A1C076FC +BF60AE9B +CBF56B80 +11038EE3 +4B78AA1C +59C72649 +D687CF08 +B182CC2E +43E4B13A +83126FE9 +EB042718 +627C8807 +47474E59 +3D317A4 +33919B88 +E00CD1A3 +3CC1F4AF +2E91597C +CDDAF2BE +3D3A18D6 +5BD6E47E +3D6A5286 +456410A0 +2B51CF4E +B55046FA +FA43946F +F90AC852 +A064AFA3 +F84235C4 +D316F3D2 +1BB0D769 +46905EBA +255EE03A +EB4D2C17 +6AFFB5CF +D755618F +ABECFB93 +594CBE9A +362C1B5 +ADFAAF67 +ECF2110C +E86FA43A +C789EFB4 +D9FDCC95 +F81FFEBB +C239F63C +16BBBF2F +B1AFC20E +B00BCEFB +D6B41A49 +A5856CBF +E2753B3C +8C03166E +537BA621 +B268C813 +C1B8E5B7 +1FCDD47C +BB257FF0 +37B89618 +6AD0F548 +C5EB6B1 +482EAE33 +1F898EA +C161076A +8112502F +77D0C22B +B1EF60B9 +D8122593 +D0ED144 +A258567E +7FCB11B8 +FC01313B +8A39DE11 +B9612887 +FAF9C5E9 +AFB24528 +C51F261D +15A83256 +E560FDB +5749D494 +61C88749 +F7C9978C +41583770 +73AF53AF +EDB828F7 +5B9A931F +B33EEF56 +3ED0DC67 +915BF5B +CD090180 +3659A346 +E09A572 +B0EB23 +F35F97ED +8708879A +E3761150 +FBCA868 +8EE5D700 +67931F7B +E3819B8F +FA9DD938 +3C3DD434 +FB62C866 +9D6A734E +2BE14923 +7ED6D7BE +423CF38D +CC4C4156 +898F3254 +405B1D62 +25995FCB +C062465 +12471B35 +6DB351F2 +5F23ABC5 +49EF7D2C +91B401B3 +85DE49E0 +81D81230 +9824E09D +767C5312 +E0744F5 +D99A77B9 +7657BA4F +46CA1289 +5D2AEFAC +ECDA74CB +DBA899D3 +AFC6E7B2 +DA79D8BB +F6508AA8 +6D0E5BF +76DD66F3 +DAA00B8F +C7EB98CF +65189199 +FC2F2235 +4F19D2CD +48D4E497 +67A7643D +777B5F1E +2F089D44 +4E841850 +2D371993 +B3ADA2E9 +421A44E9 +1D470C4D +81DA8998 +71D42D8D +E5F09965 +24BDEA19 +F8FB47FE +1CA01D53 +52A53F9B +B13279A7 +840C17AF +F27507D8 +36AA55D1 +29616808 +E5C25388 +404F7A96 +AF6CAD43 +AA2A8D86 +6D0D5DE5 +B60B5047 +F904AAE0 +9BCCB969 +73FFDDAF +AEC2E379 +DDC3B6E3 +85273FF +4F23EA7 +F1048821 +432CA7F7 +FEEFB49D +2749D00 +F0914942 +878203C4 +AB657B2F +FF754E6E +2A1B63BB +2B094F6C +8DD98DF4 +7E8810E3 +D17A81B6 +BF297F6D +FAE3391B +B28655B9 +2B4507BB +702B2563 +FFC8858A +B8DF3A03 +80018970 +4387C2E2 +81246EAC +1201F4B3 +9AF9F9B6 +29F63494 +98A87F7B +C637C322 +BCFB7066 +3505C623 +10BE77F4 +BE44797A +2EF31DB +C8DB4396 +FA7C2378 +AD3C30C3 +C3AEB714 +58183DA +5D961567 +1E42A328 +94430ED5 +866A3D67 +84B148EA +C823439 +80B57816 +D6395105 +B389CD22 +B574BF88 +F12CE1CF +C5B892E4 +94F6CE69 +9387A05E +C806C5C5 +B2823B0D +64F1253B +DD3B64F8 +4C6980E +BA9825C0 +573D9CE3 +A78DB442 +FB5510FE +C45DE1A4 +66DFA70F +47960901 +68D725DA +ACAE1E6B +60F9360 +8C9D39E +E78D5AE3 +A1A0BB75 +80E4ACAF +A0FD5042 +5E0CBC82 +C0474CF6 +840ADEA6 +6F972DE8 +5D16E0D1 +86688917 +E08A3150 +BB5FB87 +2EE82F9C +62867EB6 +B592C066 +64852270 +7A7634F0 +58C6FA6D +E83506E1 +7DC3ADA6 +E972E4D5 +4877FABF +CB37BA71 +7BD3131E +9CA64901 +C072094E +A28F50EC +CBBE833A +225D213F +D4266D98 +3DA08099 +22481B45 +899C4804 +3A8630B2 +7227F512 +FDA1F80E +E5515F91 +6EECC93B +4611F561 +47AD2CF3 +ED2A807A +D694C082 +6DEB43CE +9DBD4F70 +8C918F0D +28C5219F +EB23A332 +AAAACB21 +9B053C22 +6C5AEEBE +B1941AF2 +DEFAA083 +255DAF18 +B513F3E8 +CDE47DE0 +43DD2231 +71BA21A +AB772E2E +510C581D +93A91FFB +ED683872 +E561882C +C503A74E +E274473E +3F7D95C2 +AD48EE4C +887342AA +F4D0DC01 +68023FEA +F996EC8B +F4E33500 +8191511B +AFE0184C +8A6D392B +EDFEA13A +AC3E90B2 +94E7E8DF +76F491E4 +D45224EF +D32B9CD0 +C7167945 +2D56F7E1 +994E7AAB +65EDCC15 +AEAF497A +BA11EA7A +53D5812F +DF05201B +10A9356 +ADAEF92 +508293CC +B45B1908 +DD8C2367 +A385DBEF +A77E11BF +DE9B1792 +A9FFDB94 +AE48AD8B +E7798E96 +BAAF5B51 +44648397 +80303BBA +FBE848C0 +74F37EC6 +C9C0EE6E +1D80DBC0 +6CA37DEC +995387B6 +BA2D99D0 +D1869967 +39D0BB45 +36E391CD +12D6AB0F +4CB16A65 +8BED7413 +99987FE8 +55BD54E3 +5568C11B +F63606C4 +AC4D0747 +3032CADB +52407898 +C461B987 +1F3C8122 +C7E1B1FA +BC1BF34A +724843D7 +2DAB612E +F5180E4E +67FE89A9 +B7641E8E +185E5197 +5FDD9BA3 +C6AC4D7E +DB020625 +16ED5F8D +5A2DB8DB +58F7DE17 +8231D332 +9977723E +CFF39DC3 +A8B71C3E +3335D9BC +D34AE6FB +31559150 +E6494443 +D6C0C713 +515C9C4F +AA09B03F +EB32806D +981F48D +DAB324BE +33EDC165 +88011009 +F1120840 +48119894 +137409C1 +7F45314A +DD74A5A7 +C2251ABF +AA45B420 +4ACBA24E +D020B449 +50E55E0F +D78DD382 +F6E82B05 +9957DCE +1410E573 +CA93CF29 +83DBB1D9 +7AD6D5D4 +7921516F +8399BEB7 +DF07D89D +77AB752E +6D6DBA45 +890771BA +E87CBF52 +F90A7590 +78967761 +6617D522 +2EEDE919 +F28BA9E9 +E1E3AA90 +2CBEBEF8 +1D8A37FB +9CE04F02 +680B5A92 +561178BA +A19545D0 +DBDA24E8 +A7863CD1 +F1B829CD +2BCBD34A +B8DFF2A6 +2787D144 +A075B93E +AA7BC361 +B560CBA7 +F8E79316 +417B968B +9FF31C37 +F88ADDD1 +99A6E199 +D3D400B5 +79F33397 +4AF6EA07 +93EC79F3 +F7D9C5B8 +81D7EE3C +2898D7DC +4B8F67DB +D52D0F0B +10766E32 +E228EA2C +54C96B61 +74A99589 +7E60A886 +8FAF588 +634DD09 +1258CA8E +13E40785 +20861E8F +69BF3004 +E91E2BC8 +583A44C3 +36FD8D36 +572B4202 +BE43EB2C +65F871F3 +723C1C02 +65EBEF48 +8DD407C6 +513D6B1B +150993D3 +4C771124 +A18E6FE4 +C46071C8 +D824EA73 +7A54B17A +4AB1E70C +F7D078B5 +A315F9A4 +9A39A8C8 +CD34D2A6 +8CDEF63D +B273EFA6 +E15B8FB4 +BA2A092B +E540DF83 +33A3B82E +13BB16A4 +4AA79F4 +DCF1D80E +65B77A7E +80CB308 +9A407BA2 +D32D62B0 +DB34DA97 +109F323F +4B07538E +40AD97F +A810835D +6637380B +1ED7261B +DA642F4D +309A47D6 +9009C0E9 +7D9D6E1E +580CCE0B +67F92DAA +1936087F +342D9739 +A191FAF4 +2EF56C33 +EAB9AD66 +FB6E4FF8 +E58333E1 +E42B465D +2D61F572 +9FA12447 +848394C4 +599C9E50 +28675899 +8610332C +968735B8 +ACE06F66 +266C841B +8512CA53 +A25D3088 +D55264D0 +AC3678A9 +D1DF668E +5BEBD716 +DE986F08 +17DB60F5 +B88254C7 +BCA0E5B2 +E78B3459 +494B6F35 +5E0408F6 +A8638621 +62C27360 +8D98C864 +37EDB15B +ADC93344 +4197C21 +FEFE1A30 +ACD03EBB +A3A230A3 +45741EE4 +DE86AD8D +CDBB302B +303A5D5D +A42863D5 +9019ADA8 +EB8E036C +A5558A5D +A4D5AF4B +F04E0726 +C5AEA4BE +FCB9BC09 +3FF2E51A +53E510E9 +86FB3D5B +3031BBDC +1294451B +48879312 +972E95C1 +B8B861CE +FD180B55 +F2930D40 +31C5CF76 +8C132827 +CD696B0C +1446B194 +436D712D +9089677B +493A420F +DF82C186 +377516B8 +20ED2C1E +956EA0C3 +D26B4EEF +BFE59283 +B4D36719 +67B01DDD +6F3CA60 +BF6B98D +1B120FBA +7CF4D06 +83091BF6 +7D3F5D85 +D3E48FAD +E3025BBD +CA30F611 +64D1D991 +6A688C9 +D06F9682 +D346BF +E4DC58EB +4C4F7AB5 +9D5CBB9F +5536C074 +CCD9D1E4 +FADD0C6F +769C50EF +A1F0E40D +72EF3FEF +C421D7AC +182D7491 +3FDDA320 +49F136EE +4EFABBAA +7228A4DE +40A616A9 +EA37E4ED +5DADA164 +2F9C5671 +4D3D4CD3 +3A68B35E +7A26619D +11A14309 +D886253C +8F545687 +3666D9FB +131A5557 +9644C9A3 +FCC47DF7 +7CCDF226 +9FCBB958 +9DB97B96 +630B5596 +1B592B4C +2AB5341F +5817D559 +3C0A5FBE +F65E3830 +1D38ABAB +353E9D4 +41647BE0 +63DC6FC7 +CABC6846 +A7B8001D +2C018A1D +435D877E +3E5F838C +9709BC31 +ACA0EA75 +86A06AB +DBB06480 +2A09283F +D3A83953 +90967E13 +D055B4E1 +3365DA22 +E3FFD521 +50205ED7 +E907F5E6 +4D7D054C +C66CA376 +2A72C5C6 +793120B3 +170AC5FD +C4CFDAA2 +21A3CE3A +19F354F0 +FCE7F112 +279C9605 +AA9FBB98 +E269592C +B8E5DE7F +AE0A77D5 +45B4CF97 +6E9EE4C1 +C31F7C62 +D9E8C76C +75925FEC +EE34024B +73FEA2CD +BC601F7D +75776A1F +AC2A0090 +AA6E1956 +64C62B96 +D73C3066 +2F9C7E78 +7F1529BF +5974399A +79D31554 +2D559A9A +458A1BE +A820156A +26764010 +981D62C3 +A5C8534B +F8A5FAE0 +69EA2102 +2F62B77 +2AE14076 +88EB9A0A +36B5EF31 +73E63D55 +D6A15D81 +F5C8A216 +1EEFBC6A +8F16F5B6 +87064008 +7EEAA78F +35A4B04C +AE70F49 +9642CC0B +3199A9B1 +F0E6FE1C +F682DFA +E500C5B1 +AA1132D6 +3B3A2D9F +86C9A21E +BE1422DB +2218AF29 +64512A76 +C4624FF3 +F4E52FE4 +8473989E +269C4193 +B67528F3 +76FD1A6F +ACF6869B +DCEBBBFD +3ED92226 +3FEA0905 +2C4A131E +4CC5DF7B +63E3A62 +988BE035 +BB06A621 +61C2E087 +C2E46B3F +78010D43 +9EC6DFEB +3781CAAF +6D000EA0 +7E952EA8 +2874E849 +FAA54995 +45DB5F56 +8CB1094F +336FA04C +8CCD3F1C +A40704F0 +7AC652EF +83E998AF +8167F5FD +AA7527B6 +543AF979 +F21F16B6 +9A4E00F +1686D0AC +FB0EF404 +EBA9E0F4 +1A9BCC03 +F66D4C53 +4328EB30 +DF52A096 +4A61DDDE +3F19448E +5F3E0EDC +C9FEB2B1 +D8EDCB6 +4EAE672C +47FB8C0A +B4D64E67 +7F5AA323 +38796C27 +3ED30872 +6241EEE1 +AAFD55B6 +F31CA43A +54CE5828 +6D9103FC +665303B +ACD9B1CC +4961E187 +EEDB6D29 +544577B0 +9CC76FDC +718802FC +2EDC02F0 +6735768 +FC351962 +30F3C426 +7BD3050D +4C19A7C +97DC5F3C +720D7F42 +2F735FAA +B067A6FB +4F5EF847 +F500ABE8 +FD9E7B9E +8C37652E +B6189BE1 +BAEF411D +2584FC7F +FEA99C78 +873C71EE +51491598 +8BCC9600 +60A2176C +9D6D9475 +94E1A54E +78124EEF +4DDDA3D5 +DE77F79C +67E3A57B +1E75B5B5 +290C7ADC +30FDC46D +63BDBBD7 +9E61B234 +666593DE +8C7C1E27 +9C723CAF +EF1F2DDE +CA69CD52 +4DE571F3 +A0AD3A46 +902EB90 +D761B7BB +9F209F04 +15B1B5F +5C389CFF +B736B159 +97994EC +A2DBE074 +353360C5 +19E771B +94A72285 +2F4706A0 +64CC6476 +627BE8B7 +90FE94EA +7D02778 +2EEDEFD1 +9A5EF7C +E7B7B437 +F21A3517 +F33DF1F0 +7A865164 +4BFE70A7 +88A8B45C +C0D320E2 +E93442D3 +AA086067 +11B873ED +1BE002FE +2E799A3 +2AACAAA0 +EB1A91C7 +9FA88D6D +4D956843 +75FB8348 +1584A0EB +4C9D1E1A +413548BF +FA0CF448 +90D1256 +BEB74BF9 +EE7C6510 +765277BA +A6081E2D +E616DE16 +EDFB0495 +12EDC382 +DA64FCA3 +E258DCC3 +92E0B54B +B41B389A +D818F160 +F8F1A55D +17916C31 +DBC21683 +3272DA3 +931C08B3 +9F8EA606 +232CB0D7 +EC870992 +B5F586AB +3ECEF68A +BF7BE567 +2C009224 +C2BE6397 +90EE0A64 +FC3E6BC3 +F1190F98 +1D05D7F8 +52AA90F8 +FF7C45B0 +7F5579FE +6609C7B +9B56CD69 +4A6830B1 +ECF9E86F +62331FA4 +294B7FAB +DC7DFBA7 +4DFA98F8 +CA6447C5 +B0416FDF +5FAD4523 +BBBEA8BD +47DA6D1D +FB598321 +E4A1EBBB +DD0CD41D +77FC8F60 +E4D74C7F +E4B2B064 +52EF568C +91E87E37 +FAF6069 +6E28131E +4D39B103 +59A3C4EC +3AA49C6E +D90E743 +44FC3B9A +7D181041 +AD89A0E7 +616A565F +129B06C1 +907298A +5E98085E +9648A06 +4FE2BFCA +F73FCCCC +62DC849B +BB543EC0 +EF301310 +9801EC66 +43557EE0 +2C382E49 +5151FB5C +3C1DCC5B +DD1C153B +77B3F30 +FDE0F3E1 +C967E75E +D5C68278 +6CC1FA37 +A3FED046 +5DE77F4E +FB7F40F6 +2C9191BB +D089B672 +1E9C6BAC +756468C2 +13352B81 +D2CC73C6 +55B4D4BD +8D6BD8F4 +65F7C5C0 +34A629D9 +79424449 +1CE03FD7 +451FC3D3 +255B39FA +F5F01286 +D1623E81 +4B33EB3D +CB2326EC +9C1189DE +1ED995BA +1298FE00 +A5FDB07F +D80D48D +575374E6 +3664F373 +5ED3FE +2171B235 +413BEA38 +FD67D4A +34F10135 +F4544A59 +16BA37D6 +649879DE +EE8D839B +A545FEF1 +4573F79 +D53FE034 +F4418DBF +92181012 +FB81741F +376DF3DE +19763A21 +47FB6EB7 +7F997F6A +CB94D301 +36461AC2 +A3C2378C +2541AE5 +67D92471 +EC619D04 +3BE21ECC +A441FB3D +A19F0955 +39492084 +6C680626 +C8D37B17 +68B215A0 +8B3846B1 +9B21F1DE +8021097 +EBCC81B2 +E9310566 +AD50FB31 +AF65F01B +739CBC38 +35573201 +F7F58733 +4015ACA +6AA65104 +33202FD0 +B5B1AE8B +C1C66F1C +8BA3BEC9 +E55A2ED0 +49ABBD4B +42DD0652 +A936340A +8EE63409 +5C64BE2D +4D47E9F +745994DC +7CCF78A6 +516C7BF5 +395F9C6 +58E11E54 +73EAA341 +E2D4631A +C3552D0F +4CF36F47 +3FE7034B +EEFCB8C6 +8219943B +E800BB09 +55544B91 +A3292FE8 +89BC5746 +F63B4EE1 +E866DAF9 +E99B2D4B +BB57E938 +34FB7E1A +EBB559C1 +24838BA +48075561 +9E621607 +998E5D98 +DFCF97D6 +2ECF6FC5 +15EE774F +C3E53B77 +8EF5F879 +763B1F55 +5C90BD9 +267E7FCE +625E8032 +F12724C8 +635FC29F +36AF3D44 +B7D2299C +6E8F0DBE +A76006D5 +723C72E0 +ECA467C2 +5C7DFAD4 +23AC163E +F306D785 +67972062 +57D31D2C +4038D82E +D21756BD +257A9123 +BE96CEDC +917019D1 +362C4F33 +2A305FAF +D4389CC3 +4C435238 +D68F1F0C +372B2979 +A7D6B646 +53A2E4C2 +19E556E +62D716A7 +64918481 +4D3AA8F0 +BA8C6B54 +2468C102 +499AD5B3 +81AE28CD +42E94077 +C969675A +341B58FE +41159415 +ADE3FA94 +FF5F42BA +379C83ED +A7E678F +C2D60CBB +CC75230C +A12B9169 +9CF6EE67 +2DD905D3 +EACCF580 +367F9A41 +477BB16D +8438B576 +756D14EF +980599BD +C181C6AD +99A3EF95 +151D4F12 +CD85DFB7 +695F12C9 +4CF48772 +CB00E50D +B9E2AF4C +97EC19E3 +54810B59 +EC4F2D89 +ED77DA60 +19451088 +D5A52E95 +F6FAA3D3 +F2458DDF +D5AB6D8 +D4042924 +AEBEC90 +505DB6D0 +52505B2A +ED9CB8B3 +DB06312E +C508C5AF +4279ED2F +5C72A874 +15E22E84 +54E967EE +80A13FE3 +EE346264 +3569BCA7 +9AA9263B +2BEC95EA +966F3368 +B74F6A2B +25ADEA56 +30A1BCE9 +71EE7AB3 +74807D9C +E4C0D662 +A62305A1 +6B9FB6F0 +C2CAB758 +E3FA413E +5266648 +754C0A13 +C4FD0D47 +BEFA676C +786AFDA7 +297AA674 +F2895DA0 +72A98C20 +A662B307 +54DFB586 +8147050E +CF7C5819 +760EC4AA +F011339D +2D496BE5 +6FD43E03 +1DFD893E +814ADCDF +B7C38DCA +2149763D +EB58B9BA +9F1B81B2 +94C15E0C +5A9923B7 +6C4E0E11 +C63C3D44 +BF9AA840 +1A3E83C5 +B81CEED7 +7E9FD999 +C1A15CFF +B28F657F +287D5990 +8DB5B01E +E241144B +EB0EA64E +884A8775 +99F5DBEA +3DBB21D6 +CC9472CE +B932014E +22A35325 +7B22DCF6 +882BB2C3 +B47CDAE +28767633 +ED17CB12 +6302A17F +25D91C08 +4D61BFB6 +FA240AD0 +E9DBF560 +F0E9AD0E +835C152D +61E5F126 +C176F8FB +B793DC1C +622E04B +D9FB6072 +60124DA7 +8BEA323D +6C496459 +FBE1E578 +F1C73C9E +6A7C4C58 +43F1DB50 +E9BF93AC +B7DC5C72 +2E68083B +F3DE081F +AAA39D71 +73406424 +B99D0139 +E4FB0C67 +142AB82D +3312CC57 +7A3BEDB7 +6B6E42D2 +F8330EA0 +2FE05DA6 +3E6BB118 +3C73E09 +5FDB1471 +6A226A31 +88792727 +78708ED3 +7A095177 +9CCAD23E +C3B75180 +226F8D4C +46DD1DBE +D799BE11 +1F852432 +7361585D +97380EF8 +4F1A8127 +2EB7A73C +35B892A7 +933075A1 +2B6D3BEB +BCDCA6F1 +E9409A22 +3A8E5575 +E37AE0CA +97C2866C +BA575BC0 +C16049A3 +79FED5B1 +6356E153 +98789BE6 +47B95292 +FBDEC30C +2275A4D +632C436D +FDCBB3FE +4E0ACB8D +36A77186 +593FDA25 +D9B74A5D +18021557 +3919EF9B +DDD00927 +B0C6DFEE +F761C0C7 +886DBB5 +807A21DF +778F06D1 +27A67D08 +2CBBD43E +2696EC44 +1F916066 +DE884377 +1472CADD +F30A91AE +89C35DEC +84E5487E +792613D4 +1E59B1A9 +B18BF896 +8D7034AC +A144CE10 +F2FFC2AD +2F5FBA7D +FFEDDB97 +7C506BFD +85B811DE +CC3AD4C0 +B6CC2F1 +BFD63C90 +281E81D7 +89E82B39 +E5371DE9 +5BB68ED3 +3DA62382 +3C8CBB1D +4BE92297 +878783A4 +F925E76B +77DE554E +7EB5914E +9B3F869E +F47FA82D +23E861F2 +19E38BDE +C26E5CA7 +317C9C64 +B96B12FC +F6EB43AE +F979DCAE +DD5BE081 +5B11401 +3C4A8866 +38C6F309 +2FE6DD71 +84E2BDC8 +2FA36F63 +F0D171C +8AAD8CA5 +92D5E506 +D4CF4E62 +82DFFC21 +2C686264 +CDDA9A2B +98CF101 +847DC151 +C0FEC6AC +A1638360 +DD36C966 +A6A8635A +F700C63D +48377DC5 +138CB9D1 +857331B5 +4844609F +E29224CA +A5079F42 +3B39EA92 +F020BFFE +4859CF8E +7C1B1E1E +DD95482D +24C31760 +3555FB83 +B1D20BED +403E6587 +D04E4309 +74F63A1 +EAFDC6CD +781795C6 +BA9A1FD1 +60F61FF3 +B93EE92A +7BCCFCDF +477FB17A +B508142D +D2BC8CD8 +F11D8200 +24A8149A +8F00F213 +3822F374 +E37B6219 +4727F504 +12CD7551 +5FD2779 +E8EC01F6 +29CE5CE4 +1EDDBCF9 +69AFBC0F +11B3CB87 +E39AE82B +E66CDCBF +6824DB75 +7183BE54 +12A11956 +ADA59196 +437E5E61 +F1A7F4A1 +671FDE0A +9202817E +33ABACB2 +B0705AB1 +39952407 +D3672EB1 +A03BD94B +B46D2252 +1DC47573 +EE4C78D4 +B6E4D8E0 +12C2206A +5656E1EE +4D9D4988 +35E36416 +3AC9C8F2 +2161B02C +1B5A8615 +62587331 +CC4036C +EACDCEC6 +F40C98DC +9C8FFDE9 +D87FB3C0 +C55AABE7 +1BE31E0B +C0796911 +C08C311 +E41B196D +E4FFB7A3 +2483C766 +FD348C63 +F294631A +7B74B50A +D6416CD9 +66559F6C +A7CE68E0 +ACD88C63 +BB49939B +7987A018 +E1797428 +CE39ECE8 +D7B3DA7 +8F2A3F0C +37E3C72E +21F1A24E +57AFCEF2 +AB8CF2 +15B5A4E9 +94094315 +29C3AEB6 +A56B4233 +6D57E64E +3A7399D2 +103AE960 +8B93E67E +D5193079 +767DA47D +88AEDE6F +ABCFBF34 +2650782C +7A716475 +C86C9BBA +4423420D +3AF8FD02 +72E202EE +5A264F7B +4E103072 +4DA5A0E0 +59319F97 +B54F9AC +556DF0B3 +ABAD7DC0 +2A715C13 +9D443D0F +54BDC92C +1EC2B967 +80BE3AC2 +FA646E8A +2EE396F1 +8B0315E8 +9F52B6E +DAD30422 +2E9B6CDB +8686D47A +5D9DB3C7 +717E799B +20A4D4E5 +C2DC8AE4 +F630FADD +8C7DF047 +65F4928C +BE66D11E +6004484D +C1B509AB +FAA4C75F +B3D272A0 +7FE6F083 +A54B6584 +FC3292F +4D27DDFC +A1ABC224 +872FED55 +D235AEC +27ED8546 +1B170B2A +CE9E5C0 +2267B02 +285992BD +F855CC8 +8FFB1F6F +C7BDDF81 +349B4F5F +B9B28843 +D5D532A0 +8FD7BE3C +2DB04DE8 +C7D0C2FD +B6822987 +1FE0710D +8EADA490 +A03F99CF +F3E7F902 +F56CCCA3 +CED5B6BF +D6B3DC0D +92AA9FE8 +351208D +A1C9623B +5802547D +3480D77C +404D4E65 +679025BA +905FF962 +B7130CA8 +5AFA9CFE +2A654EFC +26218A8 +473A88A +5E3534CC +771FF1E1 +EADD6296 +DF7157B3 +D48E42E8 +3D6E848B +29CD6C +68732656 +A6C6D52A +B50279FF +705B645 +6DF7F119 +34152606 +72948D92 +18BEE72 +36BE21E3 +C34FD53A +9765DFF +E5C9B4AF +4604B155 +DEAC2388 +7841FE0C +2E275885 +3EE65330 +EB66439B +FF4AB5DE +67EDA5EA +BB722F57 +6A645B7 +DE9DD302 +5AC7601D +371B5D5B +42BAC84D +21C7AA9E +F4ECBE94 +554C8B8A +B7C8BB88 +4C77DB1D +D4D8F3AC +DAB292E5 +85D906E8 +47785703 +9CEE88D4 +7DB86DB7 +694B5A34 +DE77B361 +E8DE3CB9 +315EC35A +A71943BC +C297B8CA +55EA528C +A11AF15D +1490835E +19DA117B +403B0CC3 +FF7DE389 +ED6C22E8 +6F8A8782 +7BF2BA9B +6C95F5DF +F8270769 +AB421268 +F06B05EB +8FF7DE5F +F2AB2FCD +A5EDD602 +31F05712 +3C269177 +67D92F11 +38D8D3C5 +2047013B +8E8BA724 +EB6A773 +5AF14AD1 +49910D46 +C9D6F784 +B44B09CF +1AEA48EF +2F12BD47 +10E3F7C9 +39EA8108 +B88ADC9 +19DAC1B4 +554908DC +587A0A7E +109D1E5B +1920E3CF +BC49C914 +C1EB74A7 +A5E9A494 +5FA5B8C9 +320673C2 +CE643004 +720E4075 +FDFED2FE +89C22F8E +40887408 +3235FF6B +A906F59D +F6F98F12 +7122ECA4 +4CDFCB42 +391F2365 +53AE3667 +6CCCE2E2 +44877A8A +92561CAB +DA5DE0E7 +73B898D6 +2E37229E +ABAAED3C +21087331 +58C85412 +8BB37690 +1256467F +6EE9FAF7 +DB0895D6 +954EF968 +1C7693BC +5786650F +7D441E12 +10AA9174 +492C6A3B +34374CC9 +98E59E7C +5B7BD4E0 +D1124C9F +B5B3362F +8ECC58C7 +8EB0E23E +72991400 +13DF853B +789E8DFE +D85E60DC +A168D4D +C3B6FA3A +11443EE2 +F63F9FDD +1A14A7A5 +5EEBFD5 +B24D582D +AEA8F125 +4AA038EE +5F6A1A16 +CBADD812 +340605AA +8BD8F6E9 +B85F3A6A +A585AE8C +6D12D2B3 +17C97329 +DBB835B9 +789C3DF4 +E048D462 +BECE080A +506DE5CA +63C4FA5C +7C2D8103 +689A3516 +B218BADF +8B7F0BDE +85B17891 +8888A9C6 +3DFC9FA8 +5F2859CD +FF72AE34 +9EA3FFCA +CF2194D2 +53B56E7F +C7009619 +B127FD51 +3A513DF0 +E9147D4B +2FDF3C37 +22FA1629 +61480015 +57EE267A +EE04DA43 +EB2D289C +2C102144 +B012EED +B1B339C8 +AC1EA89 +3A4420D0 +5623907B +B0613D35 +A70F1B2C +589E3EA7 +F998AB7D +9566E921 +B133DB2D +A3106F6A +EFB4518 +6AA3FB8F +C505C8DF +65032E33 +6D3942DF +333553CC +BF392E2 +6C77F980 +39211AFC +9E0B71C9 +A3BB7123 +7CE16B9A +F15BB634 +BD68DE3E +77BB27AB +BB72659C +BFA916CA +7022CF20 +EA64C93D +B61C32CC +20201879 +148DDADC +58977 +8D5CC2E6 +76E678BD +5655B362 +587EAB4A +599E3DCF +7B470038 +E87E82DB +9088EC5E +ED9F9E4C +3DD98E27 +5AFA5052 +3DF313C4 +BB22A60D +44D97BDA +601409F3 +CD1D3CFE +7EAE52D0 +41ABBAA0 +A1D7C883 +FFE2B4C9 +13717374 +9DD27EC8 +29301EF0 +87953D6C +9309161C +C91DFE7C +DD5EC452 +F6C27DF2 +43B433FD +6D16B93F +92F09DBA +ABB598EF +B49A721A +3A03EE56 +3177D3AF +5D24FD94 +FEF88FB2 +52B3170F +64264DCC +18B683B7 +6B21935F +901A396C +4601FB55 +51F2547E +DD37C23B +35E6B3DF +31ABC979 +C7223449 +ABCA9CFB +A8F57AFA +A097240 +78704130 +7F1D7661 +456C2409 +63E31F62 +FD0D4BB1 +97FCC39 +951A7C93 +893165C9 +E86163CC +25F5694C +8890910A +43F3AE36 +55D414A1 +1ADDD3BA +C7EDFDDF +5A8607BA +219D3208 +27BD79E2 +2E9EA4B8 +5D8F951A +F9E880D5 +B2C7612A +862CCCF3 +7EDC71AC +1B6EA644 +EC3AA9A0 +970224FD +6C0DD16A +C589D1B6 +71AC91EE +C75B0206 +50232786 +316AAD4D +F4D5A31B +E30CCF43 +BD72BEAD +26DE4F8F +56E97741 +9243E978 +F7E2363D +BAE2CF31 +6367CFB1 +B72ED4E6 +75216393 +4626E74F +61194364 +8D6726A8 +458611B8 +1B536E4D +837AAD1F +F5A226D8 +8BB37701 +31F19003 +8E48DEEE +9DA11E9 +3BBB5BB4 +C6F15B5D +1A53A4EB +69AADAB +4FAE6295 +F0943601 +A449516E +BF7EE395 +176B1370 +F55873EE +553FEEF0 +9F3AB09 +2539B92E +F6803BC +BAA192FB +DBB0AD5A +B9C5415 +F92D0588 +88B9E738 +A033C767 +A1CA1EFF +5AC07200 +AC60C03D +17FE20F9 +B898B9AC +51AF425E +2706FC42 +F2A258E7 +353652D7 +CF3F89EE +63A13050 +5E6A7997 +153FD92F +1D0E8614 +6E504447 +5AAEC133 +9B6E5499 +64D5EAE6 +A29CFBAB +52B44B68 +8DC7C01A +704EB2F1 +395F1F7 +7D897418 +2FC66846 +ECCE81AE +21CD8E31 +B2EFA3D4 +16C4CD41 +D6A21ED0 +944897F9 +F495D730 +B4317C3C +8C074582 +22F6A9D9 +CE4425FB +FB08BCBA +DF07A006 +293AD5BA +BD224A44 +9DA6701B +DAB46DE4 +9F88773B +57CC02C7 +7A6B68E4 +55A54D48 +BCFC1C53 +DF64F920 +A9FE6014 +4C64DB55 +5FE9345F +412A1E48 +45D41945 +23B44D08 +8D5563A2 +26E5E437 +CECDF4D0 +1BE55025 +84329F92 +37C97F8F +C3CDE976 +580955A +C79E1131 +C5BC58E7 +7D14509B +3DE94089 +1B78FE71 +49A0ECD9 +501D09B1 +F30135CD +B0FA41B4 +33B11313 +32AB01B +635EBA76 +666D7FE5 +68CCC93 +59B0ADA5 +B305CBAA +1C553509 +5E564F7C +F057084C +52811FC8 +987465B2 +461DA750 +F0C471BB +3C9D3E64 +73C920AF +355A26B9 +3A1FDD13 +CEA3F7DD +66C0687 +1319291 +9045182D +174C724D +2A491012 +BA53519F +A62B41D8 +F6E1559E +25F93E6F +2A40C5F4 +C63D1AC2 +82598002 +2B81101A +63442848 +3788BB2D +74DDC016 +214CE0F4 +9CBAA8BD +9288E1AC +EF76E528 +719E7BAE +BD579EF6 +4E6B0C62 +6285F757 +9049BDA3 +80BFE3C1 +4344B7A7 +4552F1DD +DE2C0DAC +86346BE2 +A0A897E7 +1797D93 +6CF3C7F0 +7592D9E7 +CFB46F1E +17D6FF93 +87FF1727 +198FC755 +303540EF +78C07416 +46CB391E +8D441653 +3724DA3C +860D4DDF +A99F046E +4B167D86 +E2AFCBE9 +6608F2D2 +4E49A130 +3C64B760 +958BCEB3 +8C784B24 +5E07EF07 +7E6CAC6A +B69765D8 +65897B6D +60A8FB7D +6706E0E1 +142E4310 +15C4944C +F6A075AD +3CF66DF8 +CE1EFE72 +D6495864 +2BDEFA6B +9E511045 +F2E2E9A7 +B71B03EB +15DD8D69 +65E5A555 +52C644AE +301A8F69 +35075232 +17ADE8C4 +A2C808CC +F1A4C57B +D6EE3EF3 +85942F72 +26011F23 +D4211E97 +595E1A12 +6886CE0 +FBD6F396 +D10BD980 +6615476D +4662EB8F +F80BE955 +93A6E68E +4C3D4CAA +5838D0CB +756FB6E4 +F0BC8312 +EB89BE83 +D34E119E +34F860EC +F371DC73 +BB166E0D +CE86AF89 +C177E633 +A19C1D9B +B1DCBF1B +D7310057 +2452939E +120A830 +F92A9928 +64877B92 +3D69A585 +178187B6 +146C0495 +9A3D8886 +C79478AD +9A429976 +29795A97 +32BD0034 +1EE08CD +8982284A +ED362AC4 +4A1AC734 +6FD164B3 +422ADEBA +9374B593 +BBFA8568 +1C0B26A5 +5DF68365 +CFA1D689 +1C9509C2 +1056EAC4 +D492D000 +64076487 +2C1FB65B +9E1DEBC7 +C5AECD05 +39652664 +57A1B9F9 +3652484 +E8CCF72B +CB7EC405 +7DA97E78 +7ACE1B2C +A5DC0B75 +40C14422 +777B17AF +5AA3FEDF +319C2B1C +AB8EEE5F +159D66E5 +3E479D0 +12AF93DE +55EA550A +38853E1F +FB943864 +781FA52E +4FB9C9FA +377D8866 +8411E296 +641D997F +1933684F +27A62DEF +50E15F68 +755BCD7C +5DF3466F +494A937C +8763C6BD +C04B98E0 +E9E067FF +444151AB +C5FC7398 +5EC7D30E +E0610B7E +76CEBB5 +B15D9821 +37B2D1E2 +CC1249BF +3E064388 +246B17B3 +4A342228 +529E849B +F25F250D +31F3E925 +D1112DCA +DA6A8BC9 +2A7789D8 +C0C2C72D +4BB23226 +68166638 +4EC7519F +D559B4B7 +8035E823 +DFB06DE0 +2B4B86 +83D6F12F +84AC7F7B +7139E98B +C42D8AE3 +2992AD9C +E1E24DA1 +838772BD +CA28D517 +3606947F +B9FDFA59 +6C4F8489 +76DBFFD4 +3F0BFDF6 +1B04AD1B +8BA40134 +842A54F6 +621A0DFE +1F3729FC +C53AFEFE +CD5F1E79 +D2C0C70 +30A4FF4F +D384C76 +D73B9B17 +C74DC3F9 +E5ACD113 +901E6D5D +D376A71F +57BA08F9 +17E25669 +F7485021 +BCD1B9C5 +90C1A916 +EEF9DE6E +6AD37907 +40B05A7B +4A56C1D +901093E1 +5424EEE9 +3336300D +8B1767F3 +707A4B23 +37290194 +13A5E016 +C25902C0 +5C04C3AE +B7D84F4D +D57A495F +EE168042 +1584DB78 +7DBFDBD3 +DBE2218D +9EED8CD4 +2A562C0F +C76F7E04 +8FCA82B8 +7211C54F +8E76E82C +9BAF59A6 +C1E7B9CE +28E9E29F +6746FB40 +7841DDA1 +37D07C7 +88A5CF5 +4B0B8A4E diff --git a/finn-rtllib/memstream/sim/tb_memstream.v b/finn-rtllib/memstream/sim/tb_memstream.v new file mode 100644 index 0000000000000000000000000000000000000000..d63fa30046d7c5f2c50f509174b4937374e70c13 --- /dev/null +++ b/finn-rtllib/memstream/sim/tb_memstream.v @@ -0,0 +1,369 @@ +/* + Copyright (c) 2020, Xilinx + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of FINN nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +`timescale 1ns/10ps + +module tb_memstream; + +//parameters to enable/disable axi-mm, set number of streams, set readmemh for memory, set per-stream offsets in memory, set per-stream widths +parameter CONFIG_EN = 1; +parameter NSTREAMS = 4;//1 up to 6 + +parameter MEM_DEPTH = 9216; +parameter MEM_WIDTH = 32; +parameter MEM_INIT = "./"; +parameter MEM_CHECK = "golden.dat"; + +//widths per stream +parameter STRM0_WIDTH = 32; +parameter STRM1_WIDTH = 32; +parameter STRM2_WIDTH = 32; +parameter STRM3_WIDTH = 32; +parameter STRM4_WIDTH = 1; +parameter STRM5_WIDTH = 1; + +//depths per stream +parameter STRM0_DEPTH = 2304; +parameter STRM1_DEPTH = 2304; +parameter STRM2_DEPTH = 2304; +parameter STRM3_DEPTH = 2304; +parameter STRM4_DEPTH = 1; +parameter STRM5_DEPTH = 1; + +//offsets for each stream +parameter STRM0_OFFSET = 0; +parameter STRM1_OFFSET = 2304; +parameter STRM2_OFFSET = 4608; +parameter STRM3_OFFSET = 6912; +parameter STRM4_OFFSET = 0; +parameter STRM5_OFFSET = 0; + + +reg clk; +reg rst; + +reg [31:0] config_address = 0; +reg config_ce = 0; +reg config_we = 0; +reg [31:0] config_d0 = 0; +wire [31:0] config_q0; + +//multiple wire AXI Streams +reg m_axis_0_afull; +reg m_axis_0_tready; +wire m_axis_0_tvalid; +wire [STRM0_WIDTH-1:0] m_axis_0_tdata; + +reg m_axis_1_afull; +reg m_axis_1_tready; +wire m_axis_1_tvalid; +wire [STRM1_WIDTH-1:0] m_axis_1_tdata; + +reg m_axis_2_afull; +reg m_axis_2_tready; +wire m_axis_2_tvalid; +wire [STRM2_WIDTH-1:0] m_axis_2_tdata; + +reg m_axis_3_afull; +reg m_axis_3_tready; +wire m_axis_3_tvalid; +wire [STRM3_WIDTH-1:0] m_axis_3_tdata; + +reg m_axis_4_afull; +reg m_axis_4_tready; +wire m_axis_4_tvalid; +wire [STRM4_WIDTH-1:0] m_axis_4_tdata; + +reg m_axis_5_afull; +reg m_axis_5_tready; +wire m_axis_5_tvalid; +wire [STRM5_WIDTH-1:0] m_axis_5_tdata; + +reg [MEM_WIDTH-1:0] golden[MEM_DEPTH-1:0]; +integer ptr0, ptr1, ptr2, ptr3, ptr4, ptr5; +integer done = 0; +reg [5:0] rng; + +//clock +initial begin + clk = 0; + forever #5 clk = ~clk; +end + +initial begin + rst = 1; + config_ce = 0; + m_axis_0_afull = 0; + m_axis_1_afull = 0; + m_axis_2_afull = 0; + m_axis_3_afull = 0; + m_axis_4_afull = 0; + m_axis_5_afull = 0; + m_axis_0_tready = 1; + m_axis_1_tready = 1; + m_axis_2_tready = 1; + m_axis_3_tready = 1; + m_axis_4_tready = 1; + m_axis_5_tready = 1; + repeat(100) @(negedge clk); + rst = 0; + #100 + fork + begin + $display("Starting to generate random AFULL"); + while(~done) begin + rng = $random; + m_axis_0_afull = rng[0]; + m_axis_1_afull = rng[1]; + m_axis_2_afull = rng[2]; + m_axis_3_afull = rng[3]; + m_axis_4_afull = rng[4]; + m_axis_5_afull = rng[5]; + @(negedge clk); + end + end + join +end + + +//DUT +memstream +#( + CONFIG_EN, + NSTREAMS, + MEM_DEPTH, + MEM_WIDTH, + MEM_INIT, + + //widths per stream + STRM0_WIDTH, + STRM1_WIDTH, + STRM2_WIDTH, + STRM3_WIDTH, + STRM4_WIDTH, + STRM5_WIDTH, + + //depths per stream + STRM0_DEPTH, + STRM1_DEPTH, + STRM2_DEPTH, + STRM3_DEPTH, + STRM4_DEPTH, + STRM5_DEPTH, + + //offsets for each stream + STRM0_OFFSET, + STRM1_OFFSET, + STRM2_OFFSET, + STRM3_OFFSET, + STRM4_OFFSET, + STRM5_OFFSET +) +dut +( + clk, + ~rst, + + //optional AXI-Lite interface + config_address, + config_ce, + config_we, + config_d0, + config_q0, + + //multiple output AXI Streams + m_axis_0_afull, + m_axis_0_tready, + m_axis_0_tvalid, + m_axis_0_tdata, + + m_axis_1_afull, + m_axis_1_tready, + m_axis_1_tvalid, + m_axis_1_tdata, + + m_axis_2_afull, + m_axis_2_tready, + m_axis_2_tvalid, + m_axis_2_tdata, + + m_axis_3_afull, + m_axis_3_tready, + m_axis_3_tvalid, + m_axis_3_tdata, + + m_axis_4_afull, + m_axis_4_tready, + m_axis_4_tvalid, + m_axis_4_tdata, + + m_axis_5_afull, + m_axis_5_tready, + m_axis_5_tvalid, + m_axis_5_tdata + + +); + +//stream checkers +initial begin + ptr0 = STRM0_OFFSET; + ptr1 = STRM1_OFFSET; + ptr2 = STRM2_OFFSET; + ptr3 = STRM3_OFFSET; + ptr4 = STRM4_OFFSET; + ptr5 = STRM5_OFFSET; + fork + //check stream 0 + begin + $display("Starting stream 0 checker"); + while(~done & (NSTREAMS > 0)) begin + @(negedge clk); + if(m_axis_0_tvalid) begin + if(m_axis_0_tdata != golden[ptr0]) begin + $display("Mismatch on stream 0"); + $stop(); + end + //increment pointer + ptr0 = ptr0 + 1; + //rewind pointer if it's reached end + if(ptr0 == (STRM0_OFFSET + STRM0_DEPTH)) + ptr0 = STRM0_OFFSET; + end + end + end + //check stream 1 + begin + $display("Starting stream 1 checker"); + while(~done & (NSTREAMS > 1)) begin + @(negedge clk); + if(m_axis_1_tvalid) begin + if(m_axis_1_tdata != golden[ptr1]) begin + $display("Mismatch on stream 1"); + $stop(); + end + //increment pointer + ptr1 = ptr1 + 1; + //rewind pointer if it's reached end + if(ptr1 == (STRM1_OFFSET + STRM1_DEPTH)) + ptr1 = STRM1_OFFSET; + end + end + end + + //check stream 2 + begin + $display("Starting stream 2 checker"); + while(~done & (NSTREAMS > 2)) begin + @(negedge clk); + if(m_axis_2_tvalid) begin + if(m_axis_2_tdata != golden[ptr2]) begin + $display("Mismatch on stream 2"); + $stop(); + end + //increment pointer + ptr2 = ptr2 + 1; + //rewind pointer if it's reached end + if(ptr2 == (STRM2_OFFSET + STRM2_DEPTH)) + ptr2 = STRM2_OFFSET; + end + end + end + //check stream 3 + begin + $display("Starting stream 3 checker"); + while(~done & (NSTREAMS > 3)) begin + @(negedge clk); + if(m_axis_3_tvalid) begin + if(m_axis_3_tdata != golden[ptr3]) begin + $display("Mismatch on stream 3"); + $stop(); + end + //increment pointer + ptr3 = ptr3 + 1; + //rewind pointer if it's reached end + if(ptr3 == (STRM3_OFFSET + STRM3_DEPTH)) + ptr3 = STRM3_OFFSET; + end + end + end + //check stream 4 + begin + $display("Starting stream 4 checker"); + while(~done & (NSTREAMS > 4)) begin + @(negedge clk); + if(m_axis_4_tvalid) begin + if(m_axis_4_tdata != golden[ptr4]) begin + $display("Mismatch on stream 4"); + $stop(); + end + //increment pointer + ptr4 = ptr4 + 1; + //rewind pointer if it's reached end + if(ptr4 == (STRM4_OFFSET + STRM4_DEPTH)) + ptr4 = STRM4_OFFSET; + end + end + end + //check stream 5 + begin + $display("Starting stream 5 checker"); + while(~done & (NSTREAMS > 5)) begin + @(negedge clk); + if(m_axis_5_tvalid) begin + if(m_axis_5_tdata != golden[ptr5]) begin + $display("Mismatch on stream 5"); + $stop(); + end + //increment pointer + ptr5 = ptr5 + 1; + //rewind pointer if it's reached end + if(ptr5 == (STRM5_OFFSET + STRM5_DEPTH)) + ptr5 = STRM5_OFFSET; + end + end + end + join +end + +initial begin + done = 0; + $readmemh(MEM_CHECK,golden); +// $dumpfile("wave.vcd"); +// $dumpvars(0,tb_memstream); + @(negedge rst); + #10000000 + $display("Test done!"); + done = 1; + #1000 + $finish(); +end + +endmodule diff --git a/finn-rtllib/memstream/sim/test.sh b/finn-rtllib/memstream/sim/test.sh new file mode 100644 index 0000000000000000000000000000000000000000..24767edf4ade1c6867e0c7d906e7a45bbcb987a2 --- /dev/null +++ b/finn-rtllib/memstream/sim/test.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# Copyright (c) 2020, Xilinx +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of FINN nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +./gen_memblocks.sh golden.dat +iverilog ../hdl/*.v *v -o sim +./sim + diff --git a/finn-rtllib/memstream/xgui/memstream_v1_0.tcl b/finn-rtllib/memstream/xgui/memstream_v1_0.tcl new file mode 100644 index 0000000000000000000000000000000000000000..e5cbb670da94612e8de73f48cfa4562f89e124d1 --- /dev/null +++ b/finn-rtllib/memstream/xgui/memstream_v1_0.tcl @@ -0,0 +1,383 @@ +# Copyright (c) 2020, Xilinx +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of FINN nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Definitional proc to organize widgets for parameters. +proc init_gui { IPINST } { + ipgui::add_param $IPINST -name "Component_Name" + #Adding Page + set Page_0 [ipgui::add_page $IPINST -name "Page 0"] + ipgui::add_param $IPINST -name "CONFIG_EN" -parent ${Page_0} + ipgui::add_param $IPINST -name "MEM_DEPTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "MEM_INIT" -parent ${Page_0} + ipgui::add_param $IPINST -name "MEM_WIDTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "NSTREAMS" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM0_DEPTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM0_OFFSET" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM0_WIDTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM1_DEPTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM1_OFFSET" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM1_WIDTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM2_DEPTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM2_OFFSET" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM2_WIDTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM3_DEPTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM3_OFFSET" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM3_WIDTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM4_DEPTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM4_OFFSET" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM4_WIDTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM5_DEPTH" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM5_OFFSET" -parent ${Page_0} + ipgui::add_param $IPINST -name "STRM5_WIDTH" -parent ${Page_0} + + +} + +proc update_PARAM_VALUE.CONFIG_EN { PARAM_VALUE.CONFIG_EN } { + # Procedure called to update CONFIG_EN when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.CONFIG_EN { PARAM_VALUE.CONFIG_EN } { + # Procedure called to validate CONFIG_EN + return true +} + +proc update_PARAM_VALUE.MEM_DEPTH { PARAM_VALUE.MEM_DEPTH } { + # Procedure called to update MEM_DEPTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.MEM_DEPTH { PARAM_VALUE.MEM_DEPTH } { + # Procedure called to validate MEM_DEPTH + return true +} + +proc update_PARAM_VALUE.MEM_INIT { PARAM_VALUE.MEM_INIT } { + # Procedure called to update MEM_INIT when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.MEM_INIT { PARAM_VALUE.MEM_INIT } { + # Procedure called to validate MEM_INIT + return true +} + +proc update_PARAM_VALUE.MEM_WIDTH { PARAM_VALUE.MEM_WIDTH } { + # Procedure called to update MEM_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.MEM_WIDTH { PARAM_VALUE.MEM_WIDTH } { + # Procedure called to validate MEM_WIDTH + return true +} + +proc update_PARAM_VALUE.NSTREAMS { PARAM_VALUE.NSTREAMS } { + # Procedure called to update NSTREAMS when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.NSTREAMS { PARAM_VALUE.NSTREAMS } { + # Procedure called to validate NSTREAMS + return true +} + +proc update_PARAM_VALUE.STRM0_DEPTH { PARAM_VALUE.STRM0_DEPTH } { + # Procedure called to update STRM0_DEPTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM0_DEPTH { PARAM_VALUE.STRM0_DEPTH } { + # Procedure called to validate STRM0_DEPTH + return true +} + +proc update_PARAM_VALUE.STRM0_OFFSET { PARAM_VALUE.STRM0_OFFSET } { + # Procedure called to update STRM0_OFFSET when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM0_OFFSET { PARAM_VALUE.STRM0_OFFSET } { + # Procedure called to validate STRM0_OFFSET + return true +} + +proc update_PARAM_VALUE.STRM0_WIDTH { PARAM_VALUE.STRM0_WIDTH } { + # Procedure called to update STRM0_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM0_WIDTH { PARAM_VALUE.STRM0_WIDTH } { + # Procedure called to validate STRM0_WIDTH + return true +} + +proc update_PARAM_VALUE.STRM1_DEPTH { PARAM_VALUE.STRM1_DEPTH } { + # Procedure called to update STRM1_DEPTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM1_DEPTH { PARAM_VALUE.STRM1_DEPTH } { + # Procedure called to validate STRM1_DEPTH + return true +} + +proc update_PARAM_VALUE.STRM1_OFFSET { PARAM_VALUE.STRM1_OFFSET } { + # Procedure called to update STRM1_OFFSET when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM1_OFFSET { PARAM_VALUE.STRM1_OFFSET } { + # Procedure called to validate STRM1_OFFSET + return true +} + +proc update_PARAM_VALUE.STRM1_WIDTH { PARAM_VALUE.STRM1_WIDTH } { + # Procedure called to update STRM1_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM1_WIDTH { PARAM_VALUE.STRM1_WIDTH } { + # Procedure called to validate STRM1_WIDTH + return true +} + +proc update_PARAM_VALUE.STRM2_DEPTH { PARAM_VALUE.STRM2_DEPTH } { + # Procedure called to update STRM2_DEPTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM2_DEPTH { PARAM_VALUE.STRM2_DEPTH } { + # Procedure called to validate STRM2_DEPTH + return true +} + +proc update_PARAM_VALUE.STRM2_OFFSET { PARAM_VALUE.STRM2_OFFSET } { + # Procedure called to update STRM2_OFFSET when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM2_OFFSET { PARAM_VALUE.STRM2_OFFSET } { + # Procedure called to validate STRM2_OFFSET + return true +} + +proc update_PARAM_VALUE.STRM2_WIDTH { PARAM_VALUE.STRM2_WIDTH } { + # Procedure called to update STRM2_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM2_WIDTH { PARAM_VALUE.STRM2_WIDTH } { + # Procedure called to validate STRM2_WIDTH + return true +} + +proc update_PARAM_VALUE.STRM3_DEPTH { PARAM_VALUE.STRM3_DEPTH } { + # Procedure called to update STRM3_DEPTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM3_DEPTH { PARAM_VALUE.STRM3_DEPTH } { + # Procedure called to validate STRM3_DEPTH + return true +} + +proc update_PARAM_VALUE.STRM3_OFFSET { PARAM_VALUE.STRM3_OFFSET } { + # Procedure called to update STRM3_OFFSET when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM3_OFFSET { PARAM_VALUE.STRM3_OFFSET } { + # Procedure called to validate STRM3_OFFSET + return true +} + +proc update_PARAM_VALUE.STRM3_WIDTH { PARAM_VALUE.STRM3_WIDTH } { + # Procedure called to update STRM3_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM3_WIDTH { PARAM_VALUE.STRM3_WIDTH } { + # Procedure called to validate STRM3_WIDTH + return true +} + +proc update_PARAM_VALUE.STRM4_DEPTH { PARAM_VALUE.STRM4_DEPTH } { + # Procedure called to update STRM4_DEPTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM4_DEPTH { PARAM_VALUE.STRM4_DEPTH } { + # Procedure called to validate STRM4_DEPTH + return true +} + +proc update_PARAM_VALUE.STRM4_OFFSET { PARAM_VALUE.STRM4_OFFSET } { + # Procedure called to update STRM4_OFFSET when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM4_OFFSET { PARAM_VALUE.STRM4_OFFSET } { + # Procedure called to validate STRM4_OFFSET + return true +} + +proc update_PARAM_VALUE.STRM4_WIDTH { PARAM_VALUE.STRM4_WIDTH } { + # Procedure called to update STRM4_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM4_WIDTH { PARAM_VALUE.STRM4_WIDTH } { + # Procedure called to validate STRM4_WIDTH + return true +} + +proc update_PARAM_VALUE.STRM5_DEPTH { PARAM_VALUE.STRM5_DEPTH } { + # Procedure called to update STRM5_DEPTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM5_DEPTH { PARAM_VALUE.STRM5_DEPTH } { + # Procedure called to validate STRM5_DEPTH + return true +} + +proc update_PARAM_VALUE.STRM5_OFFSET { PARAM_VALUE.STRM5_OFFSET } { + # Procedure called to update STRM5_OFFSET when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM5_OFFSET { PARAM_VALUE.STRM5_OFFSET } { + # Procedure called to validate STRM5_OFFSET + return true +} + +proc update_PARAM_VALUE.STRM5_WIDTH { PARAM_VALUE.STRM5_WIDTH } { + # Procedure called to update STRM5_WIDTH when any of the dependent parameters in the arguments change +} + +proc validate_PARAM_VALUE.STRM5_WIDTH { PARAM_VALUE.STRM5_WIDTH } { + # Procedure called to validate STRM5_WIDTH + return true +} + + +proc update_MODELPARAM_VALUE.CONFIG_EN { MODELPARAM_VALUE.CONFIG_EN PARAM_VALUE.CONFIG_EN } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.CONFIG_EN}] ${MODELPARAM_VALUE.CONFIG_EN} +} + +proc update_MODELPARAM_VALUE.NSTREAMS { MODELPARAM_VALUE.NSTREAMS PARAM_VALUE.NSTREAMS } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.NSTREAMS}] ${MODELPARAM_VALUE.NSTREAMS} +} + +proc update_MODELPARAM_VALUE.MEM_DEPTH { MODELPARAM_VALUE.MEM_DEPTH PARAM_VALUE.MEM_DEPTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.MEM_DEPTH}] ${MODELPARAM_VALUE.MEM_DEPTH} +} + +proc update_MODELPARAM_VALUE.MEM_WIDTH { MODELPARAM_VALUE.MEM_WIDTH PARAM_VALUE.MEM_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.MEM_WIDTH}] ${MODELPARAM_VALUE.MEM_WIDTH} +} + +proc update_MODELPARAM_VALUE.MEM_INIT { MODELPARAM_VALUE.MEM_INIT PARAM_VALUE.MEM_INIT } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.MEM_INIT}] ${MODELPARAM_VALUE.MEM_INIT} +} + +proc update_MODELPARAM_VALUE.STRM0_WIDTH { MODELPARAM_VALUE.STRM0_WIDTH PARAM_VALUE.STRM0_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM0_WIDTH}] ${MODELPARAM_VALUE.STRM0_WIDTH} +} + +proc update_MODELPARAM_VALUE.STRM1_WIDTH { MODELPARAM_VALUE.STRM1_WIDTH PARAM_VALUE.STRM1_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM1_WIDTH}] ${MODELPARAM_VALUE.STRM1_WIDTH} +} + +proc update_MODELPARAM_VALUE.STRM2_WIDTH { MODELPARAM_VALUE.STRM2_WIDTH PARAM_VALUE.STRM2_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM2_WIDTH}] ${MODELPARAM_VALUE.STRM2_WIDTH} +} + +proc update_MODELPARAM_VALUE.STRM3_WIDTH { MODELPARAM_VALUE.STRM3_WIDTH PARAM_VALUE.STRM3_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM3_WIDTH}] ${MODELPARAM_VALUE.STRM3_WIDTH} +} + +proc update_MODELPARAM_VALUE.STRM4_WIDTH { MODELPARAM_VALUE.STRM4_WIDTH PARAM_VALUE.STRM4_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM4_WIDTH}] ${MODELPARAM_VALUE.STRM4_WIDTH} +} + +proc update_MODELPARAM_VALUE.STRM5_WIDTH { MODELPARAM_VALUE.STRM5_WIDTH PARAM_VALUE.STRM5_WIDTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM5_WIDTH}] ${MODELPARAM_VALUE.STRM5_WIDTH} +} + +proc update_MODELPARAM_VALUE.STRM0_DEPTH { MODELPARAM_VALUE.STRM0_DEPTH PARAM_VALUE.STRM0_DEPTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM0_DEPTH}] ${MODELPARAM_VALUE.STRM0_DEPTH} +} + +proc update_MODELPARAM_VALUE.STRM1_DEPTH { MODELPARAM_VALUE.STRM1_DEPTH PARAM_VALUE.STRM1_DEPTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM1_DEPTH}] ${MODELPARAM_VALUE.STRM1_DEPTH} +} + +proc update_MODELPARAM_VALUE.STRM2_DEPTH { MODELPARAM_VALUE.STRM2_DEPTH PARAM_VALUE.STRM2_DEPTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM2_DEPTH}] ${MODELPARAM_VALUE.STRM2_DEPTH} +} + +proc update_MODELPARAM_VALUE.STRM3_DEPTH { MODELPARAM_VALUE.STRM3_DEPTH PARAM_VALUE.STRM3_DEPTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM3_DEPTH}] ${MODELPARAM_VALUE.STRM3_DEPTH} +} + +proc update_MODELPARAM_VALUE.STRM4_DEPTH { MODELPARAM_VALUE.STRM4_DEPTH PARAM_VALUE.STRM4_DEPTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM4_DEPTH}] ${MODELPARAM_VALUE.STRM4_DEPTH} +} + +proc update_MODELPARAM_VALUE.STRM5_DEPTH { MODELPARAM_VALUE.STRM5_DEPTH PARAM_VALUE.STRM5_DEPTH } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM5_DEPTH}] ${MODELPARAM_VALUE.STRM5_DEPTH} +} + +proc update_MODELPARAM_VALUE.STRM0_OFFSET { MODELPARAM_VALUE.STRM0_OFFSET PARAM_VALUE.STRM0_OFFSET } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM0_OFFSET}] ${MODELPARAM_VALUE.STRM0_OFFSET} +} + +proc update_MODELPARAM_VALUE.STRM1_OFFSET { MODELPARAM_VALUE.STRM1_OFFSET PARAM_VALUE.STRM1_OFFSET } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM1_OFFSET}] ${MODELPARAM_VALUE.STRM1_OFFSET} +} + +proc update_MODELPARAM_VALUE.STRM2_OFFSET { MODELPARAM_VALUE.STRM2_OFFSET PARAM_VALUE.STRM2_OFFSET } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM2_OFFSET}] ${MODELPARAM_VALUE.STRM2_OFFSET} +} + +proc update_MODELPARAM_VALUE.STRM3_OFFSET { MODELPARAM_VALUE.STRM3_OFFSET PARAM_VALUE.STRM3_OFFSET } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM3_OFFSET}] ${MODELPARAM_VALUE.STRM3_OFFSET} +} + +proc update_MODELPARAM_VALUE.STRM4_OFFSET { MODELPARAM_VALUE.STRM4_OFFSET PARAM_VALUE.STRM4_OFFSET } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM4_OFFSET}] ${MODELPARAM_VALUE.STRM4_OFFSET} +} + +proc update_MODELPARAM_VALUE.STRM5_OFFSET { MODELPARAM_VALUE.STRM5_OFFSET PARAM_VALUE.STRM5_OFFSET } { + # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value + set_property value [get_property value ${PARAM_VALUE.STRM5_OFFSET}] ${MODELPARAM_VALUE.STRM5_OFFSET} +} + diff --git a/src/finn/transformation/streamline/absorb.py b/src/finn/transformation/streamline/absorb.py index eb5845f198bc636e85d395b7bdf32e01b0222cf2..5a9355bcfefc57f9608490a156906e65f7672271 100644 --- a/src/finn/transformation/streamline/absorb.py +++ b/src/finn/transformation/streamline/absorb.py @@ -161,6 +161,7 @@ class Absorb1BitMulIntoMatMul(Transformation): if n.op_type == "MatMul": matmul_weight_name = n.input[1] W = model.get_initializer(matmul_weight_name) + Wdt = model.get_tensor_datatype(matmul_weight_name) assert W is not None, "Initializer for matmul weights is not set." consumer = model.find_consumer(n.output[0]) if consumer is not None and consumer.op_type == "Mul": @@ -174,8 +175,11 @@ class Absorb1BitMulIntoMatMul(Transformation): Wnew.shape == W.shape ), """Shape of new weights is not the same as the shape of the weight matrix before.""" - model.set_initializer(matmul_weight_name, Wnew) - n.output[0] = consumer.output[0] - graph.node.remove(consumer) - graph_modified = True + check_fxn = np.vectorize(lambda x: Wdt.allowed(x)) + # only absorb if permitted by W datatype + if check_fxn(Wnew).all(): + model.set_initializer(matmul_weight_name, Wnew) + n.output[0] = consumer.output[0] + graph.node.remove(consumer) + graph_modified = True return (model, graph_modified) diff --git a/tests/brevitas/test_brevitas_fc.py b/tests/brevitas/test_brevitas_fc.py index 6be2c9a255ead2cd3f9cbcceaca60816060b19bf..db18d91e3590e896e111c9e38bdc4de43872a98c 100644 --- a/tests/brevitas/test_brevitas_fc.py +++ b/tests/brevitas/test_brevitas_fc.py @@ -45,13 +45,17 @@ from finn.util.test import get_test_model_trained export_onnx_path = make_build_dir("test_brevitas_fc_") -# activation: None or DataType -@pytest.mark.parametrize("size", ["TFC", "SFC", "LFC"]) -# weight bits -@pytest.mark.parametrize("wbits", [1]) # act bits @pytest.mark.parametrize("abits", [1, 2]) +# weight bits +@pytest.mark.parametrize("wbits", [1, 2]) +# network topology / size +@pytest.mark.parametrize("size", ["TFC", "SFC", "LFC"]) def test_brevitas_fc_onnx_export_and_exec(size, wbits, abits): + if size == "LFC" and wbits == 2 and abits == 2: + pytest.skip("No LFC-w2a2 present at the moment") + if wbits > abits: + pytest.skip("No wbits > abits cases at the moment") nname = "%s_%dW%dA" % (size, wbits, abits) finn_onnx = export_onnx_path + "/%s.onnx" % nname fc = get_test_model_trained(size, wbits, abits) diff --git a/tests/end2end/test_end2end_tfc_w2a2.py b/tests/end2end/test_end2end_tfc_w2a2.py new file mode 100644 index 0000000000000000000000000000000000000000..a2318d451c4e90c374405077c73e6878add49f2e --- /dev/null +++ b/tests/end2end/test_end2end_tfc_w2a2.py @@ -0,0 +1,297 @@ +# Copyright (c) 2020, Xilinx +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of FINN nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +from pkgutil import get_data + +import pytest + +import numpy as np + +# as of Feb'20 there is a bug that segfaults ONNX shape inference if we +# import pytorch before onnx, so we make sure to import onnx first +import onnx # NOQA +import onnx.numpy_helper as nph + +import finn.transformation.fpgadataflow.convert_to_hls_layers as to_hls +from finn.core.modelwrapper import ModelWrapper +from finn.core.onnx_exec import execute_onnx +from finn.custom_op.registry import getCustomOp +from finn.transformation.fold_constants import FoldConstants +from finn.transformation.fpgadataflow.codegen_ipgen import CodeGen_ipgen +from finn.transformation.fpgadataflow.codegen_ipstitch import CodeGen_ipstitch +from finn.transformation.fpgadataflow.codegen_npysim import CodeGen_npysim +from finn.transformation.fpgadataflow.compile import Compile +from finn.transformation.fpgadataflow.create_dataflow_partition import ( + CreateDataflowPartition, +) +from finn.transformation.fpgadataflow.hlssynth_ipgen import HLSSynth_IPGen +from finn.transformation.fpgadataflow.insert_tlastmarker import InsertTLastMarker +from finn.transformation.fpgadataflow.make_deployment import DeployToPYNQ +from finn.transformation.fpgadataflow.make_pynq_driver import MakePYNQDriver +from finn.transformation.fpgadataflow.make_pynq_proj import MakePYNQProject +from finn.transformation.fpgadataflow.replace_verilog_relpaths import ( + ReplaceVerilogRelPaths, +) +from finn.transformation.fpgadataflow.set_exec_mode import SetExecMode +from finn.transformation.fpgadataflow.synth_pynq_proj import SynthPYNQProject +from finn.transformation.general import GiveReadableTensorNames, GiveUniqueNodeNames +from finn.transformation.infer_datatypes import InferDataTypes +from finn.transformation.infer_shapes import InferShapes +from finn.transformation.streamline import Streamline +from finn.util.basic import pynq_part_map +from finn.util.test import get_test_model_trained + +build_dir = "/tmp/" + os.environ["FINN_INST_NAME"] +test_pynq_board = os.getenv("PYNQ_BOARD", default="Pynq-Z1") +test_fpga_part = pynq_part_map[test_pynq_board] +target_clk_ns = 5 + + +def test_end2end_tfc_w2a2_export(): + import brevitas.onnx as bo + + tfc = get_test_model_trained("TFC", 2, 2) + bo.export_finn_onnx( + tfc, (1, 1, 28, 28), build_dir + "/end2end_tfc_w2a2_export.onnx" + ) + + +def test_end2end_tfc_w2a2_import_and_tidy(): + model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_export.onnx") + model = model.transform(InferShapes()) + model = model.transform(FoldConstants()) + model = model.transform(GiveUniqueNodeNames()) + model = model.transform(GiveReadableTensorNames()) + model = model.transform(InferDataTypes()) + model.save(build_dir + "/end2end_tfc_w2a2_tidy.onnx") + + +def test_end2end_tfc_w2a2_streamline(): + model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_tidy.onnx") + model = model.transform(Streamline()) + model.save(build_dir + "/end2end_tfc_w2a2_streamlined.onnx") + + +def test_end2end_tfc_w2a2_convert_to_hls_layers(): + model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_streamlined.onnx") + # model = model.transform(ConvertBipolarMatMulToXnorPopcount()) + # model = model.transform(absorb.AbsorbAddIntoMultiThreshold()) + # model = model.transform(absorb.AbsorbMulIntoMultiThreshold()) + # model = model.transform(RoundAndClipThresholds()) + # model = model.transform(to_hls.InferBinaryStreamingFCLayer()) + model = model.transform(to_hls.InferQuantizedStreamingFCLayer()) + model.save(build_dir + "/end2end_tfc_w2a2_hls_layers.onnx") + + +def test_end2end_tfc_w2a2_create_dataflow_partition(): + model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_hls_layers.onnx") + parent_model = model.transform(CreateDataflowPartition()) + parent_model.save(build_dir + "/end2end_tfc_w2a2_dataflow_parent.onnx") + sdp_node = getCustomOp(parent_model.graph.node[2]) + dataflow_model_filename = sdp_node.get_nodeattr("model") + dataflow_model = ModelWrapper(dataflow_model_filename) + dataflow_model.save(build_dir + "/end2end_tfc_w2a2_dataflow_model.onnx") + + +def test_end2end_tfc_w2a2_fold_and_tlastmarker(): + model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_dataflow_model.onnx") + fc0 = model.graph.node[0] + fc1 = model.graph.node[1] + fc2 = model.graph.node[2] + fc3 = model.graph.node[3] + fc0w = getCustomOp(fc0) + fc1w = getCustomOp(fc1) + fc2w = getCustomOp(fc2) + fc3w = getCustomOp(fc3) + fc0w.set_nodeattr("inFIFODepth", 50) + fc0w.set_nodeattr("SIMD", 8) + fc0w.set_nodeattr("PE", 16) + fc0w.set_nodeattr("outFIFODepth", 4) + fc1w.set_nodeattr("SIMD", 16) + fc1w.set_nodeattr("PE", 16) + fc1w.set_nodeattr("outFIFODepth", 4) + fc2w.set_nodeattr("SIMD", 16) + fc2w.set_nodeattr("PE", 16) + fc2w.set_nodeattr("outFIFODepth", 4) + fc3w.set_nodeattr("SIMD", 16) + fc3w.set_nodeattr("PE", 10) + fc3w.set_nodeattr("outFIFODepth", 50) + model = model.transform(InsertTLastMarker()) + model.save(build_dir + "/end2end_tfc_w2a2_folded.onnx") + + +def test_end2end_tfc_w2a2_gen_hls_ip(): + model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_folded.onnx") + model = model.transform(GiveUniqueNodeNames()) + model = model.transform(CodeGen_ipgen(test_fpga_part, target_clk_ns)) + model = model.transform(HLSSynth_IPGen()) + model.save(build_dir + "/end2end_tfc_w2a2_ipgen.onnx") + + +def test_end2end_tfc_w2a2_ip_stitch(): + model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_ipgen.onnx") + model = model.transform(ReplaceVerilogRelPaths()) + model = model.transform(CodeGen_ipstitch(test_fpga_part)) + model.save(build_dir + "/end2end_tfc_w2a2_ipstitch.onnx") + + +def test_end2end_tfc_w2a2_verify_dataflow_part(): + model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_ipstitch.onnx") + x = np.zeros((1, 784), dtype=np.float32) + inp_name = model.graph.input[0].name + out_name = model.graph.output[0].name + inp_dict = {inp_name: x} + # npysim + model = model.transform(CodeGen_npysim()) + model = model.transform(Compile()) + model = model.transform(SetExecMode("npysim")) + model.save(build_dir + "/end2end_tfc_w2a2_ipstitch_npysim.onnx") + ret_npysim = execute_onnx(model, inp_dict, True) + res_npysim = ret_npysim[out_name] + # node-by-node rtlsim + model = model.transform(SetExecMode("rtlsim")) + getCustomOp(model.graph.node[0]).set_nodeattr("rtlsim_trace", "default") + getCustomOp(model.graph.node[1]).set_nodeattr("rtlsim_trace", "default") + getCustomOp(model.graph.node[2]).set_nodeattr("rtlsim_trace", "default") + getCustomOp(model.graph.node[3]).set_nodeattr("rtlsim_trace", "default") + model.save(build_dir + "/end2end_tfc_w2a2_ipstitch_nodebynode_rtlsim.onnx") + ret_rtlsim_nodebynode = execute_onnx(model, inp_dict, True) + res_rtlsim_nodebynode = ret_rtlsim_nodebynode[out_name] + # whole-network (ip-stitched) rtlsim + model.set_metadata_prop("exec_mode", "rtlsim") + model.set_metadata_prop("rtlsim_trace", "whole_trace.vcd") + model.save(build_dir + "/end2end_tfc_w2a2_ipstitch_whole_rtlsim.onnx") + ret_rtlsim_whole = execute_onnx(model, inp_dict, True) + res_rtlsim_whole = ret_rtlsim_whole[out_name] + assert np.isclose(res_npysim, res_rtlsim_nodebynode).all() + assert np.isclose(res_npysim, res_rtlsim_whole).all() + + +def test_end2end_tfc_w2a2_verify_all(): + # use the streamlined model as the "golden" model for right answers + golden = ModelWrapper(build_dir + "/end2end_tfc_w2a2_streamlined.onnx") + iname = golden.graph.input[0].name + oname = golden.graph.output[0].name + raw_i = get_data("finn", "data/onnx/mnist-conv/test_data_set_0/input_0.pb") + input_tensor = onnx.load_tensor_from_string(raw_i) + x = nph.to_array(input_tensor) + # x = np.zeros(ishape, dtype=np.float32) + ret_golden = execute_onnx(golden, {iname: x}, True) + y_golden = ret_golden[oname] + # set up parent+child graph to test + # we'll use models from the previous step as the child model + parent_model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_dataflow_parent.onnx") + iname = parent_model.graph.input[0].name + oname = parent_model.graph.output[0].name + # produce results with npysim + sdp_node = getCustomOp(parent_model.graph.node[2]) + sdp_node.set_nodeattr("model", build_dir + "/end2end_tfc_w2a2_ipstitch_npysim.onnx") + ret_npysim = execute_onnx(parent_model, {iname: x}, True) + y_npysim = ret_npysim[oname] + # produce results with node-by-node rtlsim + sdp_node.set_nodeattr( + "model", build_dir + "/end2end_tfc_w2a2_ipstitch_nodebynode_rtlsim.onnx" + ) + ret_nodebynode_rtlsim = execute_onnx(parent_model, {iname: x}, True) + y_nodebynode_rtlsim = ret_nodebynode_rtlsim[oname] + # produce results with whole-network (stitched ip) rtlsim + sdp_node.set_nodeattr( + "model", build_dir + "/end2end_tfc_w2a2_ipstitch_whole_rtlsim.onnx" + ) + ret_whole_rtlsim = execute_onnx(parent_model, {iname: x}, True) + y_whole_rtlsim = ret_whole_rtlsim[oname] + assert np.isclose(y_golden, y_npysim).all() + assert np.isclose(y_golden, y_nodebynode_rtlsim).all() + assert np.isclose(y_golden, y_whole_rtlsim).all() + + +def test_end2end_tfc_w2a2_make_pynq_proj(): + model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_ipstitch.onnx") + model = model.transform(MakePYNQProject(test_pynq_board)) + model.save(build_dir + "/end2end_tfc_w2a2_pynq_project.onnx") + + +def test_end2end_tfc_w2a2_synth_pynq_project(): + model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_pynq_project.onnx") + model = model.transform(SynthPYNQProject()) + model.save(build_dir + "/end2end_tfc_w2a2_synth.onnx") + + +def test_end2end_tfc_w2a2_make_driver(): + model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_synth.onnx") + model = model.transform(MakePYNQDriver()) + model.save(build_dir + "/end2end_tfc_w2a2_pynq_driver.onnx") + + +def test_end2end_tfc_w2a2_deploy_on_pynq(): + model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_pynq_driver.onnx") + try: + ip = os.environ["PYNQ_IP"] # no fault for this one; skip if not defined + if ip == "": + pytest.skip("PYNQ board IP address not specified") + username = os.getenv("PYNQ_USERNAME", "xilinx") + password = os.getenv("PYNQ_PASSWORD", "xilinx") + target_dir = os.getenv("PYNQ_TARGET_DIR", "/home/xilinx/finn") + model = model.transform(DeployToPYNQ(ip, username, password, target_dir)) + # save the model to be able to link it to the parent + model.save(build_dir + "/end2end_tfc_w2a2_pynq_deploy.onnx") + except KeyError: + pytest.skip("PYNQ board IP address not specified") + + +def test_end2end_tfc_w2a2_run_on_pynq(): + # use the streamlined model as the "golden" model for right answers + golden = ModelWrapper(build_dir + "/end2end_tfc_w2a2_streamlined.onnx") + iname = golden.graph.input[0].name + oname = golden.graph.output[0].name + raw_i = get_data("finn", "data/onnx/mnist-conv/test_data_set_0/input_0.pb") + input_tensor = onnx.load_tensor_from_string(raw_i) + x = nph.to_array(input_tensor) + # x = np.zeros(ishape, dtype=np.float32) + # run using FINN-based execution + ret_golden = execute_onnx(golden, {iname: x}, True) + y_golden = ret_golden[oname] + # set up parent+child graph to test + # we'll use models from the previous step as the child model + parent_model = ModelWrapper(build_dir + "/end2end_tfc_w2a2_dataflow_parent.onnx") + iname = parent_model.graph.input[0].name + oname = parent_model.graph.output[0].name + try: + ip = os.environ["PYNQ_IP"] # NOQA + if ip == "": + pytest.skip("PYNQ board IP address not specified") + # produce results with npysim + sdp_node = getCustomOp(parent_model.graph.node[2]) + sdp_node.set_nodeattr("model", build_dir + "/end2end_tfc_w2a2_pynq_deploy.onnx") + ret = execute_onnx(parent_model, {iname: x}, True) + y = ret[oname] + assert np.isclose(y, y_golden).all() + + except KeyError: + pytest.skip("PYNQ board IP address not specified") diff --git a/tests/transformation/streamline/test_streamline_fc.py b/tests/transformation/streamline/test_streamline_fc.py index b287ab65265448983fcfe4f7d94d595cd5ac5343..c68561239b7c30973856fa282d20cd2afaa168ae 100644 --- a/tests/transformation/streamline/test_streamline_fc.py +++ b/tests/transformation/streamline/test_streamline_fc.py @@ -45,13 +45,17 @@ from finn.util.basic import make_build_dir export_onnx_path = make_build_dir("test_streamline_fc_") -# activation: None or DataType -@pytest.mark.parametrize("size", ["TFC", "SFC", "LFC"]) -# weight bits -@pytest.mark.parametrize("wbits", [1]) # act bits @pytest.mark.parametrize("abits", [1, 2]) +# weight bits +@pytest.mark.parametrize("wbits", [1, 2]) +# network topology / size +@pytest.mark.parametrize("size", ["TFC", "SFC", "LFC"]) def test_streamline_fc(size, wbits, abits): + if size == "LFC" and wbits == 2 and abits == 2: + pytest.skip("No LFC-w2a2 present at the moment") + if wbits > abits: + pytest.skip("No wbits > abits cases at the moment") nname = "%s_%dW%dA" % (size, wbits, abits) finn_onnx = export_onnx_path + "/%s.onnx" % nname fc = get_test_model_trained(size, wbits, abits)