# Hello World Example

## Introduction

The Hello World example is a bare-metal application that uses the UART controller of RVX to send a Hello World message to a host computer.

## Prerequisites

To run this example, you need an FPGA board that has a UART-USB bridge, a common feature on most FPGAs.

Additionally, you need to have the [RISC-V GNU Toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain) installed on your machine to build the example. You can find instructions on how to install the RISC-V GNU Toolchain in the [User Guide](../userguide.md#prerequisites).

## Building the example

Run the commands below to build the Hello World example:

```bash title="1. Clone RVX repository"
git clone https://github.com/rafaelcalcada/rvx
```

```bash title="2. Build the software for the Hello World example"
cd rvx/examples/hello_world/software && make PREFIX=/opt/riscv
```

The `PREFIX` variable must specify the folder where the [RISC-V GNU Toolchain](../userguide.md#prerequisites) is installed.

A successfull build ends with a message like this:

```title="Successful build report"
Memory init file:   build/hello_world.hex
Binary executable:  build/hello_world.elf
Disassembly:        build/hello_world.objdump

Memory usage report (MEMORY_SIZE = 8K)
      text       data        bss      total filename
       240          0          0        240 hello_world.elf
```

The `hello_world.hex` file generated by the build process will be used in the next step to initialize the memory of RVX.

## Implementing on an FPGA

<h4>Creating the Hello World module</h4>

Using your preferred text editor, create a Verilog file name `hello_world.v` and add the source code below. Make sure to modify `hello_world.v` as follows:

- Change the `MEMORY_INIT_FILE` parameter to the absolute path of the `hello_world.hex` file you generated in the previous step.
- Change the `CLOCK_FREQUENCY` parameter to the frequency (in Hertz) of the `clock` input.

```verilog title="hello_world.v"
module hello_world (

  input   wire clock,
  input   wire reset,
  output  wire uart_tx

  );

  // Reset button debouncing
  reg reset_debounced;
  always @(posedge clock) begin
    reset_debounced <= reset;
  end

  rvx #(

  // Please adjust these two parameters accordingly
  .CLOCK_FREQUENCY          (50000000                   ),
  .MEMORY_INIT_FILE         ("/path/to/hello_world.hex" )

  ) rvx_instance (

  .clock                    (clock                      ),
  .reset                    (reset_debounced            ),
  .uart_tx                  (uart_tx                    ),

  // Unused inputs need to be hardwired to zero
  .halt                     (1'b0                       ),
  .uart_rx                  (1'b0                       ),
  .gpio_input               (1'b0                       ),
  .poci                     (1'b0                       ),

  // Unused outputs can be left open  
  .gpio_oe                  (                           ),
  .gpio_output              (                           ),
  .sclk                     (                           ),
  .pico                     (                           ),  
  .cs                       (                           ));

endmodule
```

---

<h4>Synthesizing the Hello World module</h4>

To implement the `hello_world.v` module on your FPGA, follow the steps below:

1. Open the EDA tool provided by your FPGA vendor (e.g., AMD Vivado, Intel Quartus, Lattice iCEcube).

2. Include `hello_world.v` to the project and all files in the `hardware/` folder of RVX repository.

3. Create a design constraints file and map the ports of `hello_world.v` to the corresponding devices on the FPGA board.

    - Map the `uart_tx` output to the UART-USB bridge
    - Map the `reset` input to a push-button or switch
    - Map the `clock` input to the clock source

4. Run the synthesis process.

4. Generate the bitstream and, once completed, program the FPGA with it.

## Running the application

Now that the FPGA is programmed, you can see the Hello World message on a host computer with the help of a serial terminal emulator like PySerial:

- Connect the FPGA board to your computer
- Install PySerial (or other serial terminal emulator):
    
    ```
    python3 -m pip install pyserial
    ```

- Open a serial terminal

    With PySerial, a serial terminal can be opened by running:
    
    ```
    python3 -m serial.tools.miniterm
    ```

    PySerial will show the available serial ports, one of which is the UART-USB bridge of the FPGA board. Choose it to connect.

- Finally, press the reset button.

You should now see the Hello World message!

## Featured boards

We provide project files for some featured FPGA boards. If you have one of the boards listed below, please follow the specific steps for your board:

### Arty A7

- Build the Hello World application as instructed in [Building the example](#building-the-example)
- On AMD Vivado, click __Tools / Run Tcl Script__

    Select `examples/hello_world/boards/arty_a7/create_project_arty_a7_<variant>.tcl`, where `<variant>` is the variant of your board (either 35T or 100T).

- Click **Generate Bitstream** and program the FPGA as usual
- Run the example as instructed in [Running the application](#running-the-application)

### Cmod A7

- Build the Hello World application as instructed in [Building the example](#building-the-example)
- On AMD Vivado, click __Tools / Run Tcl Script__

    Select `examples/hello_world/boards/cmod_a7/create_project_cmod_a7.tcl`.

- Click **Generate Bitstream** and program the FPGA as usual
- Run the example as instructed in [Running the application](#running-the-application)

</br>
</br>