cal_poly_carp /  CARP_SOC_2023

Created
Maintained by cal_poly_carp
Cal Poly Computer Architecture Research Project (CARP)'s SoC, SRAM, and Peripherals, set up to measure reliability in a radioactive environment.  |   https://github.com/Cal-Poly-RAMP/tapeout-ci-2311
Members 1
Peter-Herrmann committed a year ago

Cal Poly CARP SOC

CI

Architecture Overview

CARP drawio

The CARP SOC is composed of 2 RISC-V RV32I processors, a primary processor (the "CARP Core") and a processor that manages and monitors the CARP Core (the "Monitor Core"). The processors each have their own address space, volatile and (off-chip) non-volatile memory, clocks, resets, and peripherals. The Monitor Core and its peripherals have their documentation here, while the CARP Core and its peripherals are documented below.

OBI Bus And Peripherals

Memory Map

The main memory interconnect used on the SoC is a subset of OpenHW Group's Open Bus Interface (OBI). The subset we are using is the same subset used by OpenHW Groups's RI5CY Core, and its behavior is fully described in the OBI-1 specification.

Start Address End Address Section
0x0000_0000 0x0000_0FFF Bootloader
0x0000_1000 0x0FFF_FFFF --
0x1000_0000 0x1000_1FFF Peripheral Register File
0x1000_1000 0x1FFF_FFFF --
0x2000_0000 0x3FFF_FFFF 512Mb Flash
0x4000_0000 0x7FFF_FFFF --
0x8000_0000 0x8000_4FFF 20 kB SRAM
0x8000_5000 0xEFFF_FFFF --
0xF000_0000 0xF000_0003 Monitor Interrupt Generator
0xF000_0004 0xFFFF_FFFF --

Boot ROM and Boot Configs

On boot, the core resets the program counter to an address based on the boot_sel input.

boot_sel copy_boot_sel Program Counter Reset Address Function
0 0 0x0000_0000 Copies 512 words from QSPI (starting from 0x2000_0000 into SRAM), then jumps to SRAM at 0x8000_0000.
0 1 0x0000_0000 Jumps to QSPI at 0x2000_0000 and begins executing in place.
1 x 0x8000_0000 Starts execution from the internal SRAM.
This assumes that the caravel has loaded a program into the SRAM prior to startup.

XIP QSPI Flash Controller (QSPI_1)

The QSPI controller at 0x2000_0000 can support up to 512MB external QSPI memory. This flash can be programmed via the housekeeping SPI (SPI_0) in pass-thru mode. There is a 32 bit control register located at address 0x3FFF_FFFF, described below.

Bit(s) Description
31 MEMIO Enable (reset=1, set to 0 to bit bang SPI commands)
30:23 Reserved (read 0)
22 DDR Enable bit (reset=0)
21 QSPI Enable bit (reset=0)
20 CRM Enable bit (reset=0)
19:16 Read latency (dummy) cycles (reset=8)
15:12 Reserved (read 0)
11:8 IO Output enable bits in bit bang mode
7:6 Reserved (read 0)
5 Chip select (CS) line in bit bang mode
4 Serial clock line in bit bang mode
3:0 IO data bits in bit bang mode

The following settings for CRM/DDR/QSPI modes are valid:

CRM QSPI DDR Read Command Byte Mode Byte
0 0 0 03h Read N/A
0 0 1 BBh Dual I/O Read 0xFF
1 0 1 BBh Dual I/O Read 0xA5
0 1 0 EBh Quad I/O Read 0xFF
1 1 0 EBh Quad I/O Read 0xA5
0 1 1 EDh DDR Quad I/O Read 0xFF
1 1 1 EDh DDR Quad I/O Read 0xA5

Monitor Interrupt Generator

There is a 3 bit interrupt vector for the Monitor Core that can be generated by the CARP SOC by writing to address 0xF000_0000. The two least significant bits are generated by the two least significant bits of the write data, and the third bit of the interrupt vector is reserved for hardware-generated interrupts

irq[2] irq[1] irq[0]
Hardware Error Write Data bit 1 Write Data bit 0

Wishbone-OBI Bridge

The wishbone port on the SOC allows the Monitor Core to read and write to the CARP Core's SRAM, as long as the wishbone enable control is set (see Logic Analyzer). The SRAM is located at address 0x3000_0000 in the wishbone address space. The Wishbone-OBI bridge handles clock domain crossing, protocol conversion, and address translation.

OBI Bus Protocol

The specific signals are enumerated below:

Pin Name Pin Count Direction Description
req 1 Controller -> Memory Asserted by the controller to request a memory transaction. The controller is responsible to keep all address signals valid while req is high.
gnt 1 Memory -> Controller Asserted by the memory system when new transactions can be accepted. A transaction is accepted on the rising edge of the clock if req and gnt are both high.
addr 32 Controller -> Memory Address output from the controller to access memory location
we 1 Controller -> Memory Asserted by the controller to indicate a write operation
be 4 Controller -> Memory Byte enable output (strobe), to specify which bytes should be accessed
wdata 32 Controller -> Memory Write data output from the controller to be written to memory
rvalid 1 Memory -> Controller Asserted by the memory system to signal valid read data. The read response is completed on the first rising clock edge when rvalid is asserted. rdata must be valid as long as rvalid is high.
rdata 32 Memory -> Controller Read data input to the controller from the memory system

IO Assignment

GPIO Pins

There are 38 user-programmable IO pins:

Pin # Input Pin Output Pin Output Enable Description
0 JTAG x x reserved
1 x SPI_0_SDO 1 SPI 0 (Housekeeping SPI)
2 SPI_0_SDI x 0 SPI 0 (Housekeeping SPI)
3 SPI_0_CSB x 0 SPI 0 (Housekeeping SPI)
4 SPI_0_SCK x 0 SPI 0 (Housekeeping SPI)
5 copy_boot_sel x x 1 = copy 512 words from flash to SRAM and jump to SRAM. 0 = jump to flash.
6 boot_sel x x Hard select for the bootloader. (see Boot ROMs)
7 rst_hard_n x x Hard reset input, such as for a reset button (active low)
8 x o_qspi_cs_n 0 QSPI chip select (active low)
9 x o_qspi_sck 0 QSPI clock
10 i_qspi_dat[0] o_qspi_dat[0] Determined by o_qspi_mod QSPI data bit 0
11 i_qspi_dat[1] o_qspi_dat[1] Determined by o_qspi_mod QSPI data bit 1
12 i_qspi_dat[2] o_qspi_dat[2] Determined by o_qspi_mod QSPI data bit 2
13 i_qspi_dat[3] o_qspi_dat[3] Determined by o_qspi_mod QSPI data bit 3
14 (Peripherals)
15 (Peripherals)
16 (Peripherals)
17 (Peripherals)
18 (Peripherals)
19 (Peripherals)
20 (Peripherals)
21 (Peripherals)
22 (Peripherals)
23 (Peripherals)
24 (Peripherals)
25 (Peripherals)
26 (Peripherals)
27 (Peripherals)
28 (Peripherals)
29 (Peripherals)
30 (Peripherals)
31 (Peripherals)
32 (Peripherals)
33 (Peripherals)
34 (Peripherals)
35 (Peripherals)
36 (Peripherals)
37 (Peripherals)

Logic Analyzer Pins

There are 128 logic analyzer io pins controllable from the caravel.

Pin #'s Signal Name Description
3:0 reset_soft_n As long as the value 0xA is written to this nibble, the user area will reset
7:4 wishbone_enable As long as the value 0xA is written to this nibble, the data port of the onboard RAM will be given to the wishbone bus. The CARP core will not have access to the RAM.
11:8 halt_clock As long as a 0xA is written to this nibble, the clock will be held in its current position (high or low).
14:12 la_mux Logic Analyzer sample channel MUX select. The channels (see "Sample Channels" below) can be selected between using these bits.
15 clk_masked System On Chip Clock
127:16 Sample Channels 112 Bit digital sample channels. These can be selected between using la_mux.

Logic Analyzer Sample Channels

Pin # CH 0 CH 1 CH 2 CH 3 CH 4 CH 5 CH 6 CH 7
16 dmem_addr[0] imem_addr[0] sram_d_muxed_addr[0] sram_i_addr[0] peripheral_addr[0] rf_port1_reg[0] gpio_i[5] p_interrupts[0]
17 dmem_addr[1] imem_addr[1] sram_d_muxed_addr[1] sram_i_addr[1] peripheral_addr[1] rf_port1_reg[1] gpio_i[6] p_interrupts[1]
18 dmem_addr[2] imem_addr[2] sram_d_muxed_addr[2] sram_i_addr[2] peripheral_addr[2] rf_port1_reg[2] gpio_i[7] p_interrupts[2]
... ... ... ... ... ... ... ... ...
20 dmem_addr[4] imem_addr[4] sram_d_muxed_addr[4] sram_i_addr[4] peripheral_addr[4] rf_port1_reg[4] gpio_i[9] p_interrupts[4]
21 dmem_addr[5] imem_addr[5] sram_d_muxed_addr[5] sram_i_addr[5] peripheral_addr[5] rf_rs1[0] gpio_i[10] p_interrupts[5]
... ... ... ... ... ... ... ... ...
47 dmem_addr[31] imem_addr[31] sram_d_muxed_addr[31] sram_i_addr[31] peripheral_addr[31] rf_rs1[26] gpio_i[36] p_interrupts[31]
48 dmem_req imem_req sram_d_muxed_req sram_i_req peripheral_req rf_rs1[27] gpio_i[37] p_interrupts[32]
49 dmem_gnt imem_gnt sram_d_muxed_gnt sram_i_gnt peripheral_gnt rf_rs1[28] gpio_o[5] p_interrupts[33]
50 dmem_we imem_we sram_d_muxed_we sram_i_we peripheral_we rf_rs1[29] gpio_o[6] p_interrupts[34]
51 dmem_be[0] imem_be[0] sram_d_muxed_be[0] sram_i_be[0] peripheral_be[0] rf_rs1[30] gpio_o[7] p_interrupts[35]
52 dmem_be[1] imem_be[1] sram_d_muxed_be[1] sram_i_be[1] peripheral_be[1] rf_rs1[31] gpio_o[8] p_interrupts[36]
53 dmem_be[2] imem_be[2] sram_d_muxed_be[2] sram_i_be[2] peripheral_be[2] rf_port2_reg[0] gpio_o[9] p_interrupts[37]
54 dmem_be[3] imem_be[3] sram_d_muxed_be[3] sram_i_be[3] peripheral_be[3] rf_port2_reg[1] gpio_o[10] p_interrupts[38]
55 dmem_rvalid imem_rvalid sram_d_muxed_rvalid sram_i_rvalid peripheral_rvalid rf_port2_reg[2] gpio_o[11] p_interrupts[39]
56 dmem_rdata[0] imem_rdata[0] sram_d_muxed_rdata[0] sram_i_rdata[0] peripheral_rdata[0] rf_port2_reg[4] gpio_o[12] p_interrupts[40]
57 dmem_rdata[1] imem_rdata[1] sram_d_muxed_rdata[1] sram_i_rdata[1] peripheral_rdata[1] rf_port2_reg[5] gpio_o[13] p_interrupts[41]
58 dmem_rdata[2] imem_rdata[2] sram_d_muxed_rdata[2] sram_i_rdata[2] peripheral_rdata[2] rf_rs2[0] gpio_o[14] p_interrupts[42]
... ... ... ... ... ... ... ... ...
67 dmem_rdata[11] imem_rdata[11] sram_d_muxed_rdata[11] sram_i_rdata[11] peripheral_rdata[11] rf_rs2[9] gpio_o[23] p_interrupts[51]
68 dmem_rdata[12] imem_rdata[12] sram_d_muxed_rdata[12] sram_i_rdata[12] peripheral_rdata[12] rf_rs2[10] gpio_o[24] p_i_enable[0]
... ... ... ... ... ... ... ... ...
81 dmem_rdata[25] imem_rdata[25] sram_d_muxed_rdata[25] sram_i_rdata[25] peripheral_rdata[25] rf_rs2[23] gpio_o[37] p_i_enable[13]
82 dmem_rdata[26] imem_rdata[26] sram_d_muxed_rdata[26] sram_i_rdata[26] peripheral_rdata[26] rf_rs2[24] gpio_oeb_no[5] p_i_enable[14]
... ... ... ... ... ... ... ... ...
87 dmem_rdata[31] imem_rdata[31] sram_d_muxed_rdata[31] sram_i_rdata[31] peripheral_rdata[31] rf_rs2[29] gpio_oeb_no[10] p_i_enable[19]
88 dmem_wdata[0] imem_wdata[0] sram_d_muxed_wdata[0] sram_i_wdata[0] peripheral_wdata[0] rf_rs2[30] gpio_oeb_no[11] p_i_enable[20]
89 dmem_wdata[1] imem_wdata[1] sram_d_muxed_wdata[1] sram_i_wdata[1] peripheral_wdata[1] rf_rs2[31] gpio_oeb_no[12] p_i_enable[21]
90 dmem_wdata[2] imem_wdata[2] sram_d_muxed_wdata[2] sram_i_wdata[2] peripheral_wdata[2] rf_wr_reg[0] gpio_oeb_no[13] p_i_enable[22]
... ... ... ... ... ... ... ... ...
94 dmem_wdata[6] imem_wdata[6] sram_d_muxed_wdata[6] sram_i_wdata[6] peripheral_wdata[6] rf_wr_reg[5] gpio_oeb_no[17] p_i_enable[26]
95 dmem_wdata[7] imem_wdata[7] sram_d_muxed_wdata[7] sram_i_wdata[7] peripheral_wdata[7] rf_wr_data[0] gpio_oeb_no[18] p_i_enable[27]
... ... ... ... ... ... ... ... ...
114 dmem_wdata[26] imem_wdata[26] sram_d_muxed_wdata[26] sram_i_wdata[26] peripheral_wdata[26] rf_wr_data[19] gpio_oeb_no[37] p_i_enable[46]
115 dmem_wdata[27] imem_wdata[27] sram_d_muxed_wdata[27] sram_i_wdata[27] peripheral_wdata[27] rf_wr_data[20] timer_intr p_i_enable[47]
116 dmem_wdata[28] imem_wdata[28] sram_d_muxed_wdata[28] sram_i_wdata[28] peripheral_wdata[28] rf_wr_data[21] m_ext_intr p_i_enable[48]
117 dmem_wdata[29] imem_wdata[29] sram_d_muxed_wdata[29] sram_i_wdata[29] peripheral_wdata[29] rf_wr_data[22] p_int_read p_i_enable[49]
118 dmem_wdata[30] imem_wdata[30] sram_d_muxed_wdata[30] sram_i_wdata[30] peripheral_wdata[30] rf_wr_data[23] csr_busy p_i_enable[50]
119 dmem_wdata[31] imem_wdata[31] sram_d_muxed_wdata[31] sram_i_wdata[31] peripheral_wdata[31] rf_wr_data[24] me_i_en p_i_enable[51]
120 miu_illegal mcause[0] mcause[8] mcause[16] mcause[24] rf_wr_data[25] - -
121 sram_illegal mcause[1] mcause[9] mcause[17] mcause[25] rf_wr_data[26] - -
122 flash_illegal mcause[2] mcause[10] mcause[18] mcause[26] rf_wr_data[27] - -
123 caravel_illegal mcause[3] mcause[11] mcause[19] mcause[27] rf_wr_data[28] - -
124 illegal_access mcause[4] mcause[12] mcause[20] mcause[28] rf_wr_data[29] - -
125 mem_err_int mcause[5] mcause[13] mcause[21] mcause[29] rf_wr_data[30] - -
126 boot_sel mcause[6] mcause[14] mcause[22] mcause[30] rf_wr_data[31] - -
127 copy_boot_sel mcause[7] mcause[15] mcause[23] mcause[31] rf_wr_en - -

Pin Descriptions (QFN64 9x9 0.5)

Pin Name Description Voltage min Voltage nom Voltage max
1 vssa2 Analog Ground 0
2 io25 IO 25 0 0.4 or (0.8 * vddio) vddio
3 io26 IO 26 0 0.4 or (0.8 * vddio) vddio
4 io27 IO 27 0 0.4 or (0.8 * vddio) vddio
5 io28 IO 28 0 0.4 or (0.8 * vddio) vddio
6 io29 IO 29 0 0.4 or (0.8 * vddio) vddio
7 io30 IO 30 0 0.4 or (0.8 * vddio) vddio
8 io31 IO 31 0 0.4 or (0.8 * vddio) vddio
9 vdda2 Analog Supply Voltage 3.3
10 vssd2 Digital Ground 0
11 io32 IO 32 0 0.4 or (0.8 * vddio) vddio
12 io33 IO 33 0 0.4 or (0.8 * vddio) vddio
13 io34 IO 34 0 0.4 or (0.8 * vddio) vddio
14 io35 IO 35 0 0.4 or (0.8 * vddio) vddio
15 io36 IO 36 0 0.4 or (0.8 * vddio) vddio
16 io37 IO 37 0 0.4 or (0.8 * vddio) vddio
17 vddio1 IO Pad Supply Voltage 1.8 3.3 5
18 vccd Core Voltage 1.62 1.8 1.98
19 N/C No connect -
20 vssa Analog Ground 0
21 resetb Digital Reset (Active Low) 0 > 0.8 * vddio vddio
22 clock 10 MHz clock 0 0.4 or (0.8 * vddio) vddio
23 vssd Digital Ground 0
24 flash_csb QSPI_0 Chip Select 0 0.4 or (0.8 * vddio) vddio
25 flash_clk QSPI_0 Clock 0 0.4 or (0.8 * vddio) vddio
26 flash_io0 QSPI_0 D0 0 0.4 or (0.8 * vddio) vddio
27 flash_io1 QSPI_0 D1 0 0.4 or (0.8 * vddio) vddio
28 gpio Single pin management GPIO 0 0.4 or (0.8 * vddio) vddio
29 vssio IO Pad Ground 0
30 vdda Analog Supply Voltage 3.3
31 io0 JTAG 0 0.4 or (0.8 * vddio) vddio
32 io1 SPI_0_SD0 0 0.4 or (0.8 * vddio) vddio
33 io2 SPI_0_SDI 0 0.4 or (0.8 * vddio) vddio
34 io3 SPI_0_CSB 0 0.4 or (0.8 * vddio) vddio
35 io4 SPI_0_SCK 0 0.4 or (0.8 * vddio) vddio
36 io5 CARP Core Copy Boot Select 0 0.4 or (0.8 * vddio) vddio
37 io6 CARP Core Boot Select 0 0.4 or (0.8 * vddio) vddio
38 vssa1 Analog Ground 0
39 vssd1 Digital Ground 0
40 vdda1 Analog Supply Voltage 3.3
41 io7 CARP Core Hard reset 0 0.4 or (0.8 * vddio) vddio
42 io8 QSPI_1 Clock 0 0.4 or (0.8 * vddio) vddio
43 io9 QSPI_1 Chip Select 0 0.4 or (0.8 * vddio) vddio
44 io10 QSPI_1 D0 0 0.4 or (0.8 * vddio) vddio
45 io11 QSPI_1 D1 0 0.4 or (0.8 * vddio) vddio
46 io12 QSPI_1 D2 0 0.4 or (0.8 * vddio) vddio
47 vdda1 Analog Supply Voltage 3.3
48 io13 QSPI_1 D3 0 0.4 or (0.8 * vddio) vddio
49 vccd1 Core Voltage 1.8 3.3 5
50 io14 IO 14 0 0.4 or (0.8 * vddio) vddio
51 io15 IO 15 0 0.4 or (0.8 * vddio) vddio
52 vssa1 Analog Ground 0
53 io16 IO 16 0 0.4 or (0.8 * vddio) vddio
54 io17 IO 17 0 0.4 or (0.8 * vddio) vddio
55 io18 IO 18 0 0.4 or (0.8 * vddio) vddio
56 vssio IO Pad Ground 0
57 io19 IO 19 0 0.4 or (0.8 * vddio) vddio
58 io20 IO 20 0 0.4 or (0.8 * vddio) vddio
59 io21 IO 21 0 0.4 or (0.8 * vddio) vddio
60 io22 IO 22 0 0.4 or (0.8 * vddio) vddio
61 io23 IO 23 0 0.4 or (0.8 * vddio) vddio
62 io24 IO 24 0 0.4 or (0.8 * vddio) vddio
63 vccd2 Core Voltage 1.62 1.8 1.98
64 vddio2 IO Pad Supply Voltage 1.8 3.3 5
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   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.