Verilog
This section describes how to develop projects using Verilog
Welcome to the Verilog section of Deploying with Sabana.
With Sabana you can deploy hardware images from Verilog source code into the cloud. This section will guide you through the details of every step of the process, from Verilog source code to interacting with a deployed instance:
  • Creating a new image
  • Creating a test program
  • Testing the image
If you prefer to describe hardware using C++ checkout the C++ section instead.

Creating images

Overall the process of creating a new image can be summarized as follows:
  • Create a new project
  • Choose the interfaces required by the project
  • Integrate your code into the new project
    • You can also think of this step as connecting your hardware to the image shell
  • Push the project to Sabana for it to be built into an image

Shells

Verilog designs are packaged using shells that expose a given set of interfaces. In the Verilog flow for every new project a sabana.v file is created. This file contains a sabana module that exposes the shell's interfaces. This is the entry point for your design:
// Ez shell with registers
module sabana (
input logic clock,
input logic reset,
input logic start,
output logic finish,
input logic [32-1:0] a_in,
output logic [32-1:0] y_out,
output logic y_valid
);
// your code here
endmodule
At the moment there are two main types of shells: Ez and AXI4.
Depending on your design requirements, you may choose to use one shell over the other. The protocol used in Ez shells is far simpler compared to AXI4.
With Ez shells you will not have to implement complex bus protocols

Ez shells

Ez shells provide a convenient mechanism to transfer data to and from your hardware design, based on the following resources:
  • Ez registers
  • Ez queues
  • Ez RAMs
Shells expose a given bus interface but also contain resources, i.e. RAMs, for them to be used by your hardware
On the following pages we will present examples demonstrating how to use each of these interfaces:
  • ​Ez registers: 32-bit integer adder
  • ​Ez queues: 32-bit integer vector adder
  • ​Ez RAMs: 32-bit integer constant and vector adder

Ez shells programming model

A typical run of an image using an Ez shell involves the following steps:
  • Write inputs to memory registers or buffers
  • Start the processing
  • Wait for the processing to finish
  • Read out the outputs from memory registers or buffers
Your hardware will need to interact with the following control signals:
  • start: Input pulsed to start the processing (active high)
  • finish: Output pulsed when processing finishes (active high)
To interact with these signals a control register is provided at offset 0x0 of the MMIO memory space. Your test program will have to use it in order to manage the state of the hardware:
  • Writing the value 1 starts the processing
  • Reading out the value 14 means the processing has finished

AXI4 shells

As the name suggests these shells expose different AXI4 based interfaces. These are the current AXI4 shells available:
  • AXI4-Lite
We are continuously working on adding more shells, i.e. more interfaces, data widths, etc. Let us know if there is a specific configuration that you would like to have!

Examples

The Sabana CLI tool generates new projects based on shells. You can define your own custom interfaces, but the tool also has some commonly used configurations.
We generate fully working examples for these configurations so they can be used as a starting point for your projects.
In the next pages we will be exploring again the hello_world example but this time taking a more in depth look at every step of the Build, Deploy, Run cycle.
Source code for all our examples can be found in our examples repository in GitHub:
GitHub - sabanaio/sabana-examples: Welcome to the Sabana Examples repository. This repo contains code examples used in the documentation. For more information, head to: https://docs.sabana.io
GitHub
Let's get to the next section to take a look at the first example of how to build and deploy an image using the Verilog flow: