Skip to content

Latest commit

 

History

History
165 lines (121 loc) · 11.9 KB

floogen.md

File metadata and controls

165 lines (121 loc) · 11.9 KB

FlooNoC generation framework

Introduction

floogen is a framework for generating FlooNoC networks on chip. It allows to generate SystemVerilog RTL code for a given network configuration given by a configuration file written in YAML format. This document describes the configuration file format and how write your own configuration file to generate a FlooNoC network.

Configuration file format

The following is an example of a configuration file for a 4x4 mesh network:

  name: example_system
  description: "Example of a configuration file"

  routing:
    route_algo: "XY"
    use_id_table: true

  protocols:
    - name: "example_axi"
      type: "AXI4"
      direction: "manager"
      data_width: 64
      addr_width: 32
      id_width: 3
      user_width: 1
    - name: "example_axi"
      type: "AXI4"
      direction: "subordinate"
      data_width: 64
      addr_width: 32
      id_width: 3
      user_width: 1

  endpoints:
    - name: "cluster"
      array: [4, 4]
      addr_range:
        base: 0x1000_0000
        size: 0x0004_0000
      mgr_port_protocol:
        - "example_axi"
      sbr_port_protocol:
        - "example_axi"

  routers:
    - name: "router"
      array: [4, 4]

  connections:
    - src: "cluster"
      dst: "router"
      src_range:
      - [0, 3]
      - [0, 3]
      dst_range:
      - [0, 3]
      - [0, 3]
      bidirectional: true

but let's go step by step.

System description

The first part of the configuration file is the system description. It is composed by the following fields:

  • name: name of the system. This will be used in the generated RTL code to name the top module and the top-level signals.
  • description: a short description of the system. This is optional and not used to generate any kind of code

Routing

The routing section describes the routing algorithm to be used in the generated network. It is composed by the following fields:

  • route_algo: the routing algorithm to be used. Currently XY-Routing (XY) and table-based (ID) routing are supported
  • use_id_table: if set to true, a system address table will be generated in the package which is used to translate system addresses to endpoint IDs or coordinates. This is always used in table-based routing and can be used in XY-Routing to translate system addresses to XY-coordinates. If XY-Routing is used and this field is set to false, the XY coordinates are automatically derived as address offsets. This is much simpler but requires that the system addresses are contiguous and the address width is large enough to address all endpoints.

The following fields are usually auto-generated by the framework, but can be overwritten if only the package is generated:

  • addr_offset_bits: The offset bits to determine the endpoint ID or XY coordinates from the system address. For instance, if you want to use the 4 MSB bits of a 32-bit address to determine the endpoint ID, this field should be set to 28. This field is only used if use_id_table is set to false.
  • num_id_bits: The number of bits used to encode the endpoint ID. This field is only used if use_id_table is set to false.
  • num_x_bits: The number of bits used to encode the X-coordinate. This field is only used if use_id_table is set to false.
  • num_y_bits: The number of bits used to encode the Y-coordinate. This field is only used if use_id_table is set to false.

Protocols

The protocols section describes the protocols used in the network. It is composed by a list of protocols, each one described by the following fields:

  • name: name of the protocol. This will be used as a reference in the framework and in the generated RTL code to name the protocol module and the protocol signals. If the narrow-wide channels are used, they need to be named narrow and wide respectively.
  • type: Currently only AXI4 is supported
  • direction: the direction of the protocol. It can be either manager or subordinate. If an endpoint is both manager and subordinate, two protocols need to be defined.
  • data_width: the data width of the protocol
  • addr_width: the address width of the protocol
  • id_width: the ID width of the protocol. Endpoints with different ID widths for the manager and subordinate protocols are supported.
  • user_width: the user width of the protocol

Endpoints

The endpoints section describes the endpoints of the network. It is composed by a list of endpoints, each one described by the following fields:

  • name: name of the endpoint. This will be used as a reference in the framework and in the generated RTL code to name the endpoint module and the endpoint signals.
  • array: the array of the endpoint. It can either be a 1D array (e.g. [4]) or a 2D array (e.g. [4, 4]). In the latter case, the first element of the array is the number of rows and the second element is the number of columns.
  • adddr_range: Every endpoint that is a subordinate needs an address range. This field describes the address range of the endpoint. See the Address Map section for more details.
  • mgr_port_protocol: the list of protocols used by the manager port of the endpoint (if any). The names defined in the protocols section need to be used here.
  • sbr_port_protocol: the list of protocols used by the subordinate port of the endpoint (if any). The names defined in the protocols section need to be used here.
  • id_offset: the ID offset of the endpoint. This is used to offset the ID of the endpoint. For instance, if the ID offset is 1, the ID of the first endpoint will be 1, the ID of the second endpoint will be 2, and so on. This is useful when the ID 0 is reserved for a special endpoint (e.g. DRAM). The id_offset can either be a single value (e.g. 1) in case of ID routing or coordinates (e.g. x: 1, y: 1) in case of XY routing. This is useful in meshes where the coordinate of the first endpoint is not (0, 0), but rather (1, 1). The id_offset is also used in XY routing to determine the location of the endpoint in the network and how to connect it to the routers.

Address Map

Each endpoint that is a subordinate needs an address range, which can be defined in different ways:

  • start and end: the start and end address of the endpoint. The size of the address range is automatically computed by the framework.
  • start and size: the start address and the size of the address range. The end address of the endpoint is automatically computed by the framework.

For arrays, it usually makes sense to define a base address with an offset for each element of the array like this:

  • base: the base address of the endpoint.
  • size: the size of the address range. This is the offset added to the address range of the next element of the array.
  • idx: the index of the endpoint in the array. This is optional and is usually automatically computed by the framework, but could be specified.

Routers

The routers section describes the routers of the network. It is composed by a list of routers, each one described by the following fields:

  • name: name of the router. This will be used as a reference in the framework and in the generated RTL code to name the router module and the router signals.
  • array: the array of the router. It can either be a 1D array (e.g. [4]) or a 2D array (e.g. [4, 4]). In the latter case, the first element of the array is the number of rows and the second element is the number of columns.
  • tree: a router structure as a tree. This is mutually exclusive with the array field. It is a list of the number of children each level has. For instance [1, 6, 4] means that one root router is created that has 6 children routers, which each have 4 children routers (in total, there will be 1 + 6 + 4*6 = 31 routers). This is useful to create a tree structure of routers.
  • auto_connect: If the auto_connect field is set to true, the framework will automatically connect the routers to each other. This is useful for meshes and trees. If the auto_connect field is set to false, the framework will not connect the routers to each other. This is useful for custom topologies. In this case, the connections need to be defined in the connections section.

Connections

The connections section describes the connections between the endpoints and the routers. It is composed by a list of connections, each one described by the following fields:

  • src: the source of the connection. It can either be an endpoint or a router. The reference name of the endpoint or router needs to be used here.
  • dst: the destination of the connection. It can either be an endpoint or a router. The reference name of the endpoint or router needs to be used here.

In case of array endpoints or routers, one of the following fields needs to be specified:

  • src_range and/or dst_range: the range of the source and destination. This is a list of ranges. Each range is a list of two elements: the start and end index of the range. The first element of the list is the range of the first dimension of the array and the second element is the range of the second dimension of the array (if any). For instance, if the source is a 4x4 array and the source range is [[0, 3], [0, 3]], the connection will be made to all the endpoints of the array. If the source is a 4x4 array and the source range is [[0, 3], [0, 0]], the connection will be made to the first row of the array.
  • src_idx and/or dst_idx: the actual index of a single endpoint or router. This is a list of indices. Each index is a list of two elements: the index of the first dimension of the array and the index of the second dimension of the array (if any). For instance, if the source is a 4x4 array and the source index is [0, 0], the connection will be made to the first endpoint of the array. If the source is a 4x4 array and the source index is [0, 1], the connection will be made to the second endpoint of the array.

In case of tree routers, you can also specify the following fields: src_lvl or dst_lvl: the level of the source or destination. This is the level of the tree where the router is located. The root router is at level 0, the children routers are at level 1, and so on. This is useful to connect endpoints to the root router or to connect endpoints to the children routers.

Running floogen

floogen is a Python package that can be installed with pip:

pip install .

Once installed, you can run floogen with the following command:

floogen -c <config_file> -o <output_dir>

where <config_file> is the configuration file and <output_dir> is the output directory where the generated RTL code will be placed.

Additonal arguments

Apart from the configuration file, floogen supports additional options to customize the generated RTL code. The following options are supported:

  • --outdir: the output directory where the generated RTL code will be placed. This is equivalent to the -o option. If it is not specified, the output is printed to stdout.
  • --only-pkg: only generate the package. This is useful if you want to test single IPs without generating a whole network.
  • --pkg-outdir: the output directory where the generated package will be placed. By default, the package in the hw folder is overwitten, since it is also the once that is used by bender for compiling the IPs. If you want to keep the original package, you can specify a different output directory here.
  • --no-format: do not format the generated RTL code. By default, the generated RTL code is formatted with verible format, for which the verible-verilog-format binary needs to be installed. If this option is set, the generated RTL code is not formatted.
  • --visualize: visualize the generated network. It will create a plot of the graph of the network. If the --outdir option is specified, the plot is saved in the output directory. Otherwise, it is shown in a window. This is mainly intended for a quick check of the generated network, not a tool for debugging.