<!--
  Copyright (c) 2016 OpenPOWER Foundation
  
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  
-->
<chapter version="5.0" xml:lang="en" xmlns="http://docbook.org/ns/docbook" xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="chapter_enable_snap">
  
  <!-- Chapter Title goes here. -->
  <title>Enable a FPGA card in SNAP</title>
  <para>On the FPGA side of SNAP diagram, there are three parts that need to consider when moving to a new FPGA card. They are (a) PSL, (b) PSL/AXI bridge (snap_core), (c) DDR memory controller (mig). And there are also some components in SNAP need to be updated for a new FPGA card. The following sections introduced the the structure of SNAP folders and scripts and the steps. </para>
  <section><title>SNAP structure</title>
    <para>Firstly, clone the repository:</para>
    <screen>
    git clone https://github.com/open-power/snap
    git submodule init
    git submodule update
    </screen>

    <figure pgwide="1" xml:id="snap-str">
        <title>SNAP structure</title>
        <mediaobject>
          <imageobject>
            <imagedata fileref="figures/snap-structure_white.png" format="PNG" scalefit="1" width="90%" align="center" />
          </imageobject>
        </mediaobject>
    </figure> 
    <para>
    All of the user-developed accelerators should be put in "<emphasis role="bold">actions</emphasis>" directory. There are already some examples there. Each "action" has its "sw", "hw", "tests", and other sub-directories.</para>
    <para>Then back to ${SNAP_ROOT}, "<emphasis role="bold">software</emphasis>" directory includes libsnap, header files and some tools. "<emphasis role="bold">hardware</emphasis>" directory is the main focus. <emphasis role="bold">deconfig</emphasis> has the config files for silent testing purpose, and <emphasis role="bold">scripts</emphasis> has the menu settings and other scripts. </para>
    <para>
    How does SNAP work and what are the files used in each step? 
    </para>
    <itemizedlist>
    <listitem><para><emphasis role="bold">make snap_config</emphasis>: The menu to select cards and other options is controlled by "script/Kconfig"</para></listitem>
    <listitem>
    <para><emphasis role="bold">make model</emphasis>: This step creates a Vivado project. It firstly calls "hardware/setup/<emphasis role="bold">create_snap_ip.tcl</emphasis>" to generate the IP files in use, then calls "hardware/setup/<emphasis role="bold">create_framework.tcl</emphasis>" to build the project. About create_framework.tcl: </para>
        <itemizedlist>
            <listitem>
            <para>It adds BSP (board support package). In CAPI1.0, it is also called PSL Checkpoint file (b_route_design.dcp) or base_image. It uses the path pointed to b_route_design.dcp and adds it into the design. In CAPI2.0, it will call the make process in capi2-bsp submodule. Submodule "capi2-bsp" reads the encrypted PSL source files, adds PCIe and Flash logic, packs them into capi2_bsp_wrap.xcix (IP container file). Then "create_framework.tcl"  adds the capi2_bsp_wrap.xcix into the design.</para>
            </listitem>
            <listitem>
            <para>It adds FPGA top files and snap_core files (in hardware/hdl/core).</para>
            </listitem>
            <listitem>
            <para>It adds constrain files: in hardware/setup/${FPGACARD} or in hardware/capi2-bsp/${FPGACARD}</para>
            </listitem>
            <listitem>
            <para>It adds user files (in actions/${ACTION_NAME}/hw). User's action hardware uses top file named "action_wrapper.vhd"</para>
            </listitem>
            <listitem>
            <para>It adds simulation files (in hardware/sim/core) including simulation top files and simulation models. (If "no_sim" is selected in snap_config menu, this step is skipped.)</para>
            </listitem>
        </itemizedlist>
	<para>After above steps, "<emphasis role="bold">viv_project</emphasis>" is created. You can open it with Vivado GUI, and check the design hierarchy. And it will call the selected simulator to compile the simulation model.</para>
    </listitem>
    <listitem>
    <para><emphasis role="bold">make image</emphasis>: This step runs synthesis, implementation and bitstream generation. It calls "hardware/setup/<emphasis role="bold">snap_build.tcl</emphasis>" and also uses some related tcl scripts to work on "viv_project". In this step, "hardware/build" will be created and the output products like bit images, checkpoints (middle products for debugging) and reports (reports of timing, clock, IO, utilization, etc.) If everything runs well and timing passes, user will get the bitstream files (in "Images" sub directory) to program the FPGA card. </para>
    </listitem>
    </itemizedlist>
  </section>

  <section><title>BSP (board support package) module</title>
     <figure pgwide="1" xml:id="base_image">
        <title>CAPI1.0: base_image (b_route_design.dcp)</title>
        <mediaobject>
          <imageobject>
            <imagedata fileref="figures/base_image.png" format="PNG" scalefit="1" width="90%" align="center" />
          </imageobject>
        </mediaobject>
    </figure> 
    <para>For CAPI1.0, base_image contains surrounding logic and the kernel logic:</para>
    <itemizedlist>
	    <listitem><para>PCIe hard IP core (pcie3_ultrascale_0)</para></listitem> 
	    <listitem><para>Flash Controller (psl_flash)</para></listitem> 
	    <listitem><para>VSEC: Vendor Specific Extended Capability (psl_vsec)</para></listitem> 
	    <listitem><para>Xilinx MultiBoot control logic (psl_xilmltbt)</para></listitem> 
	    <listitem><para>PSL kernel logic (psl)</para></listitem> 
    </itemizedlist>
    <para>The interface between base_image and AFU(psl_accel) has 5 groups of signals, described in PSL spec <link xlink:href="http://openpowerfoundation.org/wp-content/uploads/resources/psl-afu-spec/content/go01.html"> CAPI1.0 PSL/AFU interface Spec</link>.</para>
    <para>The interface between base_image and Chip IOs are card specific, and the information need to be provided by Card Vendor. Generally, they include:</para>
    <itemizedlist>
	    <listitem><para>Flash interface (usually DPIx16)</para></listitem>
	    <listitem><para>PCIe interface: perst, refclk, TX and RX data lanes</para></listitem>
	    <listitem><para>Peripheral IPs: I2C, LED, DDR, Ethernet, etc. </para></listitem>
    </itemizedlist>
    <para>Marked in light orange color, you can download the entire base_image (b_route_design.dcp) from <link xlink:href="https://www-355.ibm.com/systems/power/openpower/tgcmDocumentRepository.xhtml?aliasId=CAPI#">OpenPower Portal</link>.</para>

    <figure pgwide="1" xml:id="bsp">
        <title>CAPI2.0: capi2-bsp (capi_bsp_wrap.xcix)</title>
        <mediaobject>
          <imageobject>
            <imagedata fileref="figures/bsp.png" format="PNG" scalefit="1" width="90%" align="center" />
          </imageobject>
        </mediaobject>
    </figure>
    <para>For CAPI2.0, the structure is similar, but the PSL9 logic (marked in light orange color) is provided as an encrypted Zip package. It can be downloaded from <link xlink:href="https://www-355.ibm.com/systems/power/openpower/posting.xhtml?postingId=1BED44BCA884D845852582B70076A89A">OpenPower Portal</link> and put in "capi2-bsp/psl" directory. Then it uses the make process in capi2-bsp to generate an IP container file (capi_bsp_wrap.xcix). Please refer to the README file at <link xlink:href="https://github.com/open-power/capi2-bsp">https://github.com/open-power/capi2-bsp</link> for more details.</para>
    <para>CAPI2.0 cards are using SPI Flash interface: SPIx4 or dual SPIx4 (also mentioned as SPIx8). For PCIe Gen3, it uses 16 lanes. For PCIe Gen4, it uses 8 lanes. The interface of PSL9 has 6 groups of signals. Please refer to <link xlink:href="http://openpowerfoundation.org/wp-content/uploads/resources/v2-psl-afu-spec/content/ch_preface.html"> CAPI2.0 PSL/AFU interface Spec</link> for the details. </para>
    <note><para>The logic in snap_core (CAPI2.0) implements the data path with DMA interface. Buffer interface is not used. </para></note>
    <para>The above two figures apply to both HDK development and SNAP framework. The difference is, for HDK developers, they work on the AFU by themselves. For SNAP developers, they make use of the snap_core logic and only work on action_wrapper. The AFU part for SNAP developers contains following blocks:</para>
    <figure pgwide="1" xml:id="afu">
        <title>AFU diagram in SNAP framework</title>
        <mediaobject>
          <imageobject>
            <imagedata fileref="figures/afu.png" format="PNG" scalefit="1" width="100%" align="center" />
          </imageobject>
        </mediaobject>
    </figure>
    <para>
    AFU logic RTL files are open-sourced. Developer can make modifications for their own purpose, like adding multiple DDR channels, adding NVMe and Ethernet controllers.
    </para>

  </section>

  <section><title>Enable a new card in SNAP</title>
	  <para>For a new FPGA card, the detailed items to update can be classified into following sections:</para>
	  <itemizedlist>
	  <listitem><para>Preparations</para></listitem>
	  <listitem><para>Hardware RTL, setup, simulation</para></listitem>
	  <listitem><para>Software and tools</para></listitem>
	  <listitem><para>Testing</para></listitem>
	  <listitem><para>Publishing</para></listitem>
	  </itemizedlist>
     
    <section><title>Preppartions</title>
        <para>First, give a FPGACARD name. It should start from the company's name, following with the card ID and be short. For example. ADKU3 = Alpha-Data ADM-PCIE-KU3. Get follow information from the card vendor. (You can check the "Status" column to trace the progress.)</para>
		  <!-- A table starts -->
	<table frame="all" pgwide="1" xml:id="info1">
        <title>Information to collect</title>
        <tgroup cols="2">
          <colspec colname="c2" colwidth="15*" />
          <colspec colname="c3" colwidth="35*" />
          <thead>
            <row>
              <entry>
                <para>
                  <emphasis role="bold">Item</emphasis>
                </para>
              </entry>
              <entry>
                <para>
                  <emphasis role="bold">Description</emphasis>
                </para>
              </entry>
            </row>
          </thead>
          <tbody>
            <row>
              <entry><para>FPGACARD</para></entry>
              <entry><para>Short card name used in SNAP</para></entry>
            </row>
            <row>
              <entry><para>FPGACHIP</para></entry>
              <entry><para>FPGA part name, for example, xcvu9p-fsgd2104-2L-e</para></entry>
            </row>
            <row>
              <entry><para>Flash Type</para></entry>
              <entry><para>Flash chip that attached to FPGA, for example mt28gu01gaax1e-bpi-x16. And the related xdc files for FPGA config.</para></entry>
            </row>
            <row>
              <entry><para>DDR MC IP</para></entry>
              <entry><para>Short card name used in SNAP</para></entry>
            </row>
            <row>
              <entry><para>FPGACARD</para></entry>
              <entry><para>DDR memory controller Vivado IP tcl/xdc file. </para></entry>
            </row>
            <row>
              <entry><para>Other peripherals</para></entry>
              <entry><para>NVMe IP, Ethernet IP and so on (Optional)</para></entry>
            </row>
            <row>
              <entry><para>IO pins</para></entry>
	      <entry><para>PACKAGE_PIN for base_image or bsp: flash, pcie, i2c etc.</para>
	             <para>PACKAGE_PIN for peripheral IPs.</para></entry>
            </row>
          </tbody>
        </tgroup>
      </table>
    </section>
    <section><title>SNAP environment updates</title>
	    <para>The best way is to grep some keywords like "S241" or "AD8K5" under the directories and look for the locations that need modifications.</para>
	    <note>
	    <para>If you meet files ending with "_source", like "psl_fpga.vhd_source", that means this file will be pre-processed to generate the output file without "_source" suffix, like "psl_fpga.vhd". There are <userinput>#ifdef</userinput> macros or comments like <userinput>-- only for NVME_USED=TRUE</userinput>. They help to create a target VHDL/Verilog file with different configurations.</para>
	    </note>
	    <para>Below lists the files to change. There may be some differences with new commits in SNAP git repository. Keep in mind they include:  </para>
	    <itemizedlist>
	    <listitem><para>snap_config and environmental files</para></listitem>
	    <listitem><para>Hardware: psl_accel and psl_fpga (top) RTL files</para></listitem>
	    <listitem><para>Hardware: tcl files for the workflow</para></listitem>
	    <listitem><para>Hardware: Board: xdc files for IO/floorplan/clock/bitstream</para></listitem>
	    <listitem><para>Hardware: DDR: create_ip, sim model, xdc files</para></listitem>
	    <listitem><para>Hardware: Other IP: create_ip, sim model, xdc files</para></listitem>
	    <listitem><para>Software: New card type, register definition</para></listitem>
	    <listitem><para>Testing: jenkins</para></listitem>
	    <listitem><para>Readme and Documents</para></listitem>
	    </itemizedlist>
    <note>
    <itemizedlist>
    <listitem><para> For CAPI1.0, you need to generate a new PSL checkpoint file and upload it to OpenPower Portal. Chapter TODO describes the details.</para></listitem>
    <listitem><para> For CAPI2.0, you need to add a ${FPGACARD} directory in capi2-bsp git repository. Copy an existing folder as a start and follow the README file.</para></listitem>
    <listitem><para> Make sure the information in xdc/tcl files are permitted to be open-source.</para></listitem>
    <listitem><para> Send email to OpenPower Acceleration Workgroup or contact your representative to apply for a subsystem device ID for the new card. For example, ADKU3 uses 0x0605. S241 uses 0x0660. </para></listitem>
    <listitem><para> You also need to update <link xlink:href="https://github.com/ibm-capi/capi-utils">https://github.com/ibm-capi/capi-utils</link> to allow capi-flash-script to program this new card. Subsystem ID will be used there. It is also used in snap/software/tools/snap_find_card. </para></listitem>
    </itemizedlist>
    </note>

	<table frame="all" pgwide="1" xml:id="filelist">
        <title>Config files to change</title>
	  <tgroup cols="2">
          <colspec colname="c2" colwidth="25*" />
          <colspec colname="c3" colwidth="25*" />
          <thead>
            <row>
              <entry>
                <para>
                  <emphasis role="bold">File name</emphasis>
                </para>
              </entry>
              <entry>
                <para>
                  <emphasis role="bold">Changes done</emphasis>
                </para>
              </entry>
            </row>
          </thead>
          <tbody>
            <row>
              <entry><para>scripts/Kconfig</para></entry>
              <entry><para>adding card to the Kconfig menu. Provide Flash information (size/type/user address)</para></entry>
            </row>
            <row>
              <entry><para>hardware/doc/SNAP-Registers.md</para></entry>
              <entry><para>SNAP registers for new card - doc</para></entry>
            </row>
            <row>
              <entry><para>hardware/setup/snap_config.sh</para></entry>
              <entry><para>SNAP registers - setting</para></entry>
            </row>
          </tbody>
        </tgroup>
      </table>

      <table frame="all" pgwide="1" xml:id="rtlchange">
        <title>RTL/xdc/tcl files to change</title>
	  <tgroup cols="2">
          <colspec colname="c2" colwidth="25*" />
          <colspec colname="c3" colwidth="25*" />
          <thead>
            <row>
              <entry>
                <para>
                  <emphasis role="bold">File name</emphasis>
                </para>
              </entry>
              <entry>
                <para>
                  <emphasis role="bold">Changes done</emphasis>
                </para>
              </entry>
            </row>
          </thead>
          <tbody>
		  <row><entry><para>hardware/hdl/core/psl_accel_${FPGACARD}.vhd_source</para></entry><entry><para> specific to card</para></entry></row>
<row><entry><para>hardware/hdl/core/psl_accel_types.vhd_source</para></entry><entry><para>specific to card</para></entry></row>
<row><entry><para>hardware/hdl/core/psl_fpga_${FPGACARD}.vhd_source</para></entry><entry><para> specific to card</para></entry></row>
<row><entry><para>hardware/setup/${FPGACARD}/capi_bsp_pblock.xdc</para></entry><entry><para> specific to card</para></entry></row>
<row><entry><para>hardware/setup/${FPGACARD}/snap_${FPGACARD}.xdc</para></entry><entry><para> specific to card</para></entry></row>
<row><entry><para>hardware/setup/${FPGACARD}/snap_ddr4pins.xdc</para></entry><entry><para> specific to card</para></entry></row>
<row><entry><para>hardware/setup/build_mcs.tcl</para></entry><entry><para>declare card name</para></entry></row>
<row><entry><para>hardware/setup/create_framework.tcl</para></entry><entry><para>declare card name</para></entry></row>
<row><entry><para>hardware/setup/create_snap_ip.tcl</para></entry><entry><para>declare card name and its IP</para></entry></row>
<row><entry><para>hardware/setup/flash_mcs.tcl</para></entry><entry><para>declare card name</para></entry></row>
<row><entry><para>hardware/setup/snap_bitstream_post.tcl</para></entry><entry><para>declare card name</para></entry></row>
<row><entry><para>hardware/setup/snap_bitstream_pre.tcl</para></entry><entry><para>declare card name</para></entry></row>
<row><entry><para>hardware/setup/snap_bitstream_step.tcl</para></entry><entry><para>declare card name</para></entry></row>
<row><entry><para>hardware/setup/snap_impl_step.tcl</para></entry><entry><para>declare card name</para></entry></row>
<row><entry><para>hardware/snap_check_psl</para></entry><entry><para>declare card name</para></entry></row>
          </tbody>
        </tgroup>
      </table>

      <table frame="all" pgwide="1" xml:id="swchange">
        <title>Software files to change</title>
	  <tgroup cols="2">
          <colspec colname="c2" colwidth="25*" />
          <colspec colname="c3" colwidth="25*" />
          <thead>
            <row>
              <entry>
                <para>
                  <emphasis role="bold">File name</emphasis>
                </para>
              </entry>
              <entry>
                <para>
                  <emphasis role="bold">Changes done</emphasis>
                </para>
              </entry>
            </row>
          </thead>
          <tbody>
<row><entry><para>software/lib/snap.c</para></entry><entry><para>declare card name</para></entry></row>
<row><entry><para>software/tools/snap_find_card</para></entry><entry><para>declare card name + id</para></entry></row>
<row><entry><para>software/include/snap_regs.h</para></entry><entry><para>SNAP registers - setting</para></entry></row>
          </tbody>
        </tgroup>
      </table>

      <table frame="all" pgwide="1" xml:id="otherchange">
        <title>Other files to change</title>
	  <tgroup cols="2">
          <colspec colname="c2" colwidth="25*" />
          <colspec colname="c3" colwidth="25*" />
          <thead>
            <row>
              <entry>
                <para>
                  <emphasis role="bold">File name</emphasis>
                </para>
              </entry>
              <entry>
                <para>
                  <emphasis role="bold">Changes done</emphasis>
                </para>
              </entry>
            </row>
          </thead>
          <tbody>
<row><entry><para>actions/scripts/snap_jenkins.sh</para></entry><entry><para>jenkins tests (optional)</para></entry></row>
<row><entry><para>defconfig/{FPGACARD}*.defconfig</para></entry><entry><para>For silent jenkins testing (optional)</para></entry></row>
<row><entry><para>README.md</para></entry><entry><para>Announce a new card is supported </para></entry></row>
          </tbody>
        </tgroup>
      </table>


    </section>
  </section>
  
</chapter>



