[fpga] Remove top_earlgrey_reduce.py dependency for CW310 FPGA board

Previously, we were still using that script to keep binary compatibility
between the NexysVideo and the CW310 FPGA board. This commit removes
this dependency, adds a new device in meson, adapts the CI jobs and
modifies the documentation accordingly.

Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index c785bfe..1b38d13 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -385,9 +385,7 @@
   dependsOn:
     - lint
     # The bootrom is built into the FPGA image at synthesis time.
-    # Currently, we are still using the reduce script for the CW310 meaning we can re-use the
-    # software binaries built for the NexysVideo board.
-    - sw_build_nexysvideo
+    - sw_build
   condition: and(succeeded(), eq(dependencies.lint.outputs['DetermineBuildType.onlyDocChanges'], '0'), eq(dependencies.lint.outputs['DetermineBuildType.onlyDvChanges'], '0'))
   pool: ci-public
   timeoutInMinutes: 120 # 2 hours
@@ -396,7 +394,7 @@
   - template: ci/download-artifacts-template.yml
     parameters:
       downloadPartialBuildBinFrom:
-        - sw_build_nexysvideo
+        - sw_build
   - bash: |
       set -e
       . util/build_consts.sh
@@ -406,11 +404,9 @@
       mkdir -p "$OBJ_DIR/hw"
       mkdir -p "$BIN_DIR/hw/top_earlgrey"
 
-      ./hw/top_earlgrey/util/top_earlgrey_reduce.py
-
-      BOOTROM_VMEM="$BIN_DIR/sw/device/boot_rom/boot_rom_fpga_nexysvideo.scr.39.vmem"
+      BOOTROM_VMEM="$BIN_DIR/sw/device/boot_rom/boot_rom_fpga_cw310.scr.39.vmem"
       test -f "$BOOTROM_VMEM"
-      OTP_VMEM="$BIN_DIR/sw/device/otp_img/otp_img_fpga_nexysvideo.vmem"
+      OTP_VMEM="$BIN_DIR/sw/device/otp_img/otp_img_fpga_cw310.vmem"
       test -f "$OTP_VMEM"
 
       fusesoc --cores-root=. \
@@ -551,7 +547,6 @@
   timeoutInMinutes: 30
   dependsOn:
     - chip_earlgrey_cw310
-    - sw_build_nexysvideo
     - sw_build
   steps:
   - template: ci/install-package-dependencies.yml
@@ -559,7 +554,6 @@
     parameters:
       downloadPartialBuildBinFrom:
         - chip_earlgrey_cw310
-        - sw_build_nexysvideo
         - sw_build
   - bash: |
       set -e
diff --git a/doc/ug/getting_started_build_sw.md b/doc/ug/getting_started_build_sw.md
index e3348c8..8f83731 100644
--- a/doc/ug/getting_started_build_sw.md
+++ b/doc/ug/getting_started_build_sw.md
@@ -19,8 +19,8 @@
 $ ./meson_init.sh
 
 # Build the two targets we care about, specifically.
-$ ninja -C build-out sw/device/boot_rom/boot_rom_export_fpga_nexysvideo
-$ ninja -C build-out sw/device/examples/hello_world/hello_world_export_fpga_nexysvideo
+$ ninja -C build-out sw/device/boot_rom/boot_rom_export_fpga_cw310
+$ ninja -C build-out sw/device/examples/hello_world/hello_world_export_fpga_cw310
 
 # Build *everything*, including targets for other devices.
 $ ninja -C build-out all
diff --git a/doc/ug/getting_started_fpga.md b/doc/ug/getting_started_fpga.md
index 11e5d8f..452a56d 100644
--- a/doc/ug/getting_started_fpga.md
+++ b/doc/ug/getting_started_fpga.md
@@ -36,10 +36,8 @@
 $ ninja -C build-out all
 ```
 
-Since not all FPGAs are able to fit the full design, there is a separate script that can be invoked to reduce the size of the design.
-Note that even though the ChipWhisperer CW310 board with Xilinx Kintex 7 XC7K410T FPGA is able to hold the full OpenTitan design, it currently requires the size of the design to be reduced just like for the Nexys Video FPGA board.
-
-To reduce the design such that it fits the Nexys Video FPGA board:
+Only the ChipWhisperer CW310 board with the Xilinx Kintex 7 XC7K410T FPGA can fit the whole Earl Grey design.
+When working with the Nexys Video FPGA board, the Earl Grey design has to be modified to reduce its size using a script.
 ```console
 $ cd $REPO_TOP
 $ ./hw/top_earlgrey/util/top_earlgrey_reduce.py --build
@@ -47,6 +45,7 @@
 The `--build` argument is optional and ensures that the boot ROM is rebuilt for the reduced design.
 Alternatively, the boot ROM can be manually regenerated using the previous command.
 
+Next, the actual FPGA implementation can be started.
 In the following example we synthesize the Earl Grey design for the ChipWhisperer CW310 board using Xilinx Vivado {{< tool_version "vivado" >}}.
 To target the Nexys Video board, replace `cw310` by `nexysvideo` in the instructions below.
 
@@ -54,7 +53,6 @@
 $ . /tools/xilinx/Vivado/{{< tool_version "vivado" >}}/settings64.sh
 $ cd $REPO_TOP
 $ ./meson_init.sh
-$ ./hw/top_earlgrey/util/top_earlgrey_reduce.py
 $ ninja -C build-out all
 $ fusesoc --cores-root . run --flag=fileset_top --target=synth lowrisc:systems:chip_earlgrey_cw310
 ```
@@ -157,17 +155,16 @@
 1. Run the loading tool.
    ```console
    $ cd ${REPO_TOP}
-   $ ./util/fpga/cw310_loader.py --firmware build-bin/sw/device/examples/hello_world/hello_world_fpga_nexysvideo.bin
+   $ ./util/fpga/cw310_loader.py --firmware build-bin/sw/device/examples/hello_world/hello_world_fpga_cw310.bin
    ```
-   Note that even though targeting the ChipWhisperer CW310 board, the binary contains `nexysvideo` in its name as the software build tool currently only supports one FPGA target.
 
    This should report how the binary is split into frames:
    ```
    CW310 Loader: Attemping to find CW310 FPGA Board:
        No bitstream specified
    Board found, setting PLL2 to 100 MHz
-   INFO: Programming firmware file: build-bin/sw/device/examples/hello_world/hello_world_fpga_nexysvideo.bin
-   Programming OpenTitan with "build-bin/sw/device/examples/hello_world/hello_world_fpga_nexysvideo.bin"...
+   INFO: Programming firmware file: build-bin/sw/device/examples/hello_world/hello_world_fpga_cw310.bin
+   Programming OpenTitan with "build-bin/sw/device/examples/hello_world/hello_world_fpga_cw310.bin"...
    Transferring frame 0x00000000 @ 0x00000000.
    Transferring frame 0x00000001 @ 0x000007D8.
    Transferring frame 0x00000002 @ 0x00000FB0.
diff --git a/hw/top_earlgrey/chip_earlgrey_cw310.core b/hw/top_earlgrey/chip_earlgrey_cw310.core
index 37477a3..72321e5 100644
--- a/hw/top_earlgrey/chip_earlgrey_cw310.core
+++ b/hw/top_earlgrey/chip_earlgrey_cw310.core
@@ -10,7 +10,6 @@
       - lowrisc:systems:top_earlgrey:0.1
       - lowrisc:systems:top_earlgrey_pkg
       - lowrisc:systems:padring
-      - lowrisc:tool:chip_earlgrey_nexysvideo_size_check
     files:
       - rtl/clkgen_xil7series.sv
       - rtl/autogen/chip_earlgrey_cw310.sv
@@ -42,12 +41,12 @@
   BootRomInitFile:
     datatype: str
     description: Scrambled boot ROM initialization file in 40 bit vmem hex format
-    default: "../../../../../build-bin/sw/device/boot_rom/boot_rom_fpga_nexysvideo.scr.39.vmem"
+    default: "../../../../../build-bin/sw/device/boot_rom/boot_rom_fpga_cw310.scr.39.vmem"
     paramtype: vlogparam
   OtpCtrlMemInitFile:
     datatype: str
     description: OTP initialization file in vmem hex format
-    default: "../../../../../build-bin/sw/device/otp_img/otp_img_fpga_nexysvideo.vmem"
+    default: "../../../../../build-bin/sw/device/otp_img/otp_img_fpga_cw310.vmem"
     paramtype: vlogparam
   # For value definition, please see ip/prim/rtl/prim_pkg.sv
   PRIM_DEFAULT_IMPL:
diff --git a/sw/device/lib/arch/device.h b/sw/device/lib/arch/device.h
index 7d70e5b..cf44554 100644
--- a/sw/device/lib/arch/device.h
+++ b/sw/device/lib/arch/device.h
@@ -36,8 +36,13 @@
    */
   kDeviceSimVerilator,
   /**
-   * Represents the "Nexys Video FPGA" device, i.e., the particular FPGA board
-   * blessed for OpenTitan development, containing a Xilinx FPGA.
+   * Represents the "ChipWhisperer CW310 FPGA" device, i.e., the particular
+   * FPGA board blessed for OpenTitan development, containing a Xilinx FPGA.
+   */
+  kDeviceFpgaCw310,
+  /**
+   * Represents the "Nexys Video FPGA" device, i.e., the previous main FPGA
+   * development board for OpenTitan, containing a Xilinx FPGA.
    */
   kDeviceFpgaNexysVideo,
 } device_type_t;
diff --git a/sw/device/lib/arch/device_fpga_cw310.c b/sw/device/lib/arch/device_fpga_cw310.c
new file mode 100644
index 0000000..9ec17bb
--- /dev/null
+++ b/sw/device/lib/arch/device_fpga_cw310.c
@@ -0,0 +1,27 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "sw/device/lib/arch/device.h"
+
+/**
+ * @file
+ * @brief Device-specific symbol definitions for the ChipWhisperer CW310 device.
+ */
+
+const device_type_t kDeviceType = kDeviceFpgaCw310;
+
+const uint64_t kClockFreqCpuHz = 10 * 1000 * 1000;  // 10MHz
+
+const uint64_t kClockFreqPeripheralHz = 25 * 100 * 1000;  // 2.5MHz
+
+const uint64_t kClockFreqUsbHz = 48 * 1000 * 1000;  // 48MHz
+
+const uint64_t kUartBaudrate = 115200;
+
+const uint32_t kUartNCOValue =
+    CALCULATE_UART_NCO(kUartBaudrate, kClockFreqPeripheralHz);
+
+const uintptr_t kDeviceTestStatusAddress = 0;
+
+const uintptr_t kDeviceLogBypassUartAddress = 0;
diff --git a/sw/device/lib/arch/meson.build b/sw/device/lib/arch/meson.build
index 9f854db..974a304 100644
--- a/sw/device/lib/arch/meson.build
+++ b/sw/device/lib/arch/meson.build
@@ -16,6 +16,13 @@
   ),
 )
 
+sw_lib_arch_fpga_cw310 = declare_dependency(
+  link_with: static_library(
+    'device_fpga_cw310',
+    sources: ['device_fpga_cw310.c'],
+  ),
+)
+
 sw_lib_arch_fpga_nexysvideo = declare_dependency(
   link_with: static_library(
     'device_fpga_nexysvideo',
@@ -30,5 +37,6 @@
 sw_lib_arch_core_devices = {
   'sim_dv': sw_lib_arch_sim_dv,
   'sim_verilator': sw_lib_arch_sim_verilator,
+  'fpga_cw310': sw_lib_arch_fpga_cw310,
   'fpga_nexysvideo': sw_lib_arch_fpga_nexysvideo,
 }
diff --git a/test/systemtest/earlgrey/test_fpga_cw310.py b/test/systemtest/earlgrey/test_fpga_cw310.py
index 73baafd..f1070e1 100644
--- a/test/systemtest/earlgrey/test_fpga_cw310.py
+++ b/test/systemtest/earlgrey/test_fpga_cw310.py
@@ -65,7 +65,7 @@
     # Allow tests to optionally specify their subdir within the project.
     test_dir = app_config.get('test_dir', 'sw/device/tests')
 
-    test_filename = binary_name + '_fpga_nexysvideo.bin'
+    test_filename = binary_name + '_fpga_cw310.bin'
     bin_path = bin_dir / test_dir / test_filename
     assert bin_path.is_file()
     return bin_path