diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml new file mode 100644 index 00000000..6c3c5637 --- /dev/null +++ b/.github/workflows/publish-docs.yml @@ -0,0 +1,32 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +# Author: Tim Fischer + +name: publish-docs + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + + deploy: + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + cache: pip + - name: Install Python requirements + run: pip install .[docs] + - name: Deploy Documentation + run: mkdocs gh-deploy --force diff --git a/Makefile b/Makefile index 74ae93fa..df5061dd 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ run-sim-batch: run-vsim-batch ############ BENDER ?= bender -VSIM ?= questa-2023.4 vsim +VSIM ?= vsim SPYGLASS ?= sg_shell VERIBLE_FMT ?= verible-verilog-format VCS ?= vcs-2022.06 vcs diff --git a/README.md b/README.md index 3f671898..f83e54fa 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Logo -This repository provides modules for the FlooNoC, a Network-on-Chip (NoC) which is part of the [PULP (Parallel Ultra-Low Power) Platform](https://pulp-platform.org/). The repository includes Network Interface IPs (named chimneys), Routers and further NoC components to build a complete NoC. FlooNoC mainly supports [AXI4+ATOPs](https://github.com/pulp-platform/axi/tree/master), but can be easily extended to other On-Chip protocols. Arbitrary topologies are supported with several routing algorithms. FlooNoC is designed to be scalable and modular, and can be easily extended with new components. Additionally, FlooNoC provides a generation framework for creating customized NoC configurations. +_FlooNoC_, is a Network-on-Chip (NoC) research project, which is part of the [PULP (Parallel Ultra-Low Power) Platform](https://pulp-platform.org/). The main idea behind _FlooNoC_ is to provide a scalable high-performance NoC for non-coherent systems. _FlooNoC_ was mainly designed to interface with [AXI4+ATOPs](https://github.com/pulp-platform/axi/tree/master), but can easily be extended to other On-Chip protocols. _FlooNoC_ already provides network interface IPs (named chimneys) for AXI4 protocol, which converts to a custom-link level protocol that provides significantly better scalability than AXI4. _FlooNoC_ also includes protocol-agnostic routers based on the custom link-level protocol to transport payloads. Finally, _FlooNoC_ also include additional NoC components to assemble a complete NoC in a modular fashion. _FlooNoC_ is also highly flexible and supports a wide variety of topologies and routing algorithms. A Network generation framework called _FlooGen_ makes it possible to easily generate entire networks based on a simple configuration file.
@@ -29,13 +29,18 @@ This repository provides modules for the FlooNoC, a Network-on-Chip (NoC) which ## 💡 Design Principles -Our NoC design is grounded in the following key principles: +_FlooNoC_ design is based on the following key principles: + +1. **Full AXI4 Support**: _FlooNoC_ fully supports AXI4+ATOPs from AXI5 as outlined [here](https://github.com/pulp-platform/axi/tree/master), providing a high-bandwidth and latency-tolerant solution. _FlooNoC_ achieves this with full support for bursts and multiple outstanding transactions. + +1. **Decoupled Links and Networks**: _FlooNoC_ uses a link-level protocol that is decoupled from the network-level protocol. This allows us to move the complexity of the network-level protocol into the network interfaces, while deploying low-complexity routers in the network, that enable better scalability than multi-layer AXI networks. + +1. **Wide Physical Channels**: _FlooNoC_ uses wide physical channels to meet the high-bandwidth requirements at network endpoints without being constrained by the operating frequency. In contrast to traditional NoCs which use serialization with header and tail flits to transport a message, _FlooNoC_ avoids any kind of serialization and sends entire messages in a single flit including header and tail information. + +1. **Separation of traffic**: _FlooNoC_ addresses diverse types of traffic that can occur in non-coherent systems, by decoupling multiple links to handle wide, high-bandwidth, burst-based traffic and narrow, latency-sensitive traffic with separate physical channels. + +1. **Modularity:** The _FlooNoC_ architecture is designed with modularity in mind. It includes a set of IPs that can be instantiated together to build a NoC. This approach not only promotes reusability but also facilitates flexibility in designing custom NoCs to cater to a variety of specific system requirements. -1. **Full AXI4 Support**: Our design fully supports AXI4+ATOPs from AXI5 as outlined [here](https://github.com/pulp-platform/axi/tree/master), particularly multiple outstanding burst transactions. It utilizes low-complexity routers and a decoupled link-level protocol to ensure scalability, thereby enabling tolerance to high-latency off-chip accesses. -1. **Decoupled Links and Networks**: We use a link-level protocol that is decoupled from the network-level protocol. This allows us to move the complexity of the network-level protocol into the network interfaces, while deploying low-complexity routers in the network, that enable better scalability. -1. **Wide Physical Channels**: We incorporate wide physical channels in order to meet the high-bandwidth requirements at network endpoints without being constrained by the operating frequency. This is in contrast to the traditional narrow link approach. Further, the NoC avoids any kind of serialization and sends entire messages in a single flit including header and tail information. -1. **Separation of traffic**: Our design acknowledges the diversity in traffic patterns, as it decouples links and networks to handle wide, high-bandwidth, burst-based traffic and narrow, latency-sensitive traffic with separate physical channels. -1. **Modularity:** Our design principles also emphasize modularity. We have developed a set of IPs that can be instantiated together to build a NoC. This approach not only promotes reusability but also facilitates flexibility in designing custom NoCs to cater to a variety of specific system requirements. ## 🔮 Origin of the name diff --git a/docs/Apache-License.md b/docs/Apache-License.md new file mode 120000 index 00000000..965b606f --- /dev/null +++ b/docs/Apache-License.md @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 00000000..75cd854c --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,3 @@ +# Guide to Contributing + +TODO diff --git a/docs/SHL-License.md b/docs/SHL-License.md new file mode 120000 index 00000000..db811d44 --- /dev/null +++ b/docs/SHL-License.md @@ -0,0 +1 @@ +../LICENSE-SHL \ No newline at end of file diff --git a/docs/changelog.md b/docs/changelog.md new file mode 120000 index 00000000..04c99a55 --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1 @@ +../CHANGELOG.md \ No newline at end of file diff --git a/docs/floogen/cli.md b/docs/floogen/cli.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/floogen/connections.md b/docs/floogen/connections.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/floogen/endpoints.md b/docs/floogen/endpoints.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/floogen/known_issues.md b/docs/floogen/known_issues.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/floogen/overview.md b/docs/floogen/overview.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/floogen/protocols.md b/docs/floogen/protocols.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/floogen/routers.md b/docs/floogen/routers.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/floogen/routing.md b/docs/floogen/routing.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/getting_started.md b/docs/getting_started.md new file mode 100644 index 00000000..8b1155c7 --- /dev/null +++ b/docs/getting_started.md @@ -0,0 +1,94 @@ +# Getting Started + +## Prerequisites + +### Bender + +_FlooNoC_ uses [Bender](https://github.com/pulp-platform/bender) for hardware IPs and dependency management. Bender is available through Cargo or as pre-compiled binaries for Linux, macOS, and Windows: + +=== "Cargo" + + ```bash + cargo install bender + ``` + +=== "Precompiled" + + ```bash + curl --proto '=https' --tlsv1.2 https://pulp-platform.github.io/bender/init -sSf | sh + ``` + +Make sure that the Bender binary directory is in your `PATH`, or set the `BENDER` environment variable to the path of the Bender binary. + +### Python + +Some parts of _FlooNoC_ including the _FlooGen_ generator are written in Python. The required Python version is 3.10 or higher. You can install Python from the [official website](https://www.python.org/downloads/). + +### Simulation Tools + +Currently, we don't provide any open-source simulation setup such as Verilator. _FlooNoC_ was internally tested and verified with QuestaSim-2023.4. To run the RTL simulations you need to have QuestaSim installed. By default, _FlooNoC_ uses the `vsim` command to run the simulations, which can be overridden by setting the `VSIM` environment variable. + +## Installation + +Clone the repository from GitHub: + +```bash +git clone https://github.com/pulp-platform/FlooNoC.git +``` +Install the python dependencies and _FlooGen_: + +```bash +pip install . +``` + +## Usage + +### Running the Testbenches + +Now you can compile and run the testbenches with the following command: + +```bash +make compile-sim +make run-sim VSIM_TB_DUT=tb_floo_dut +``` + +### Generating a _FlooNoC_ Network + +where you replace `tb_floo_dut` with the testbench that you want to simulate. + +To generate a _FlooNoC_ network using the _FlooGen_ generator, you can use the following command: + +```bash +floogen -c examples/floo_dut.yaml -o generated +``` + +## Optional dependencies + +For the development on _FlooGen_, it is recommended to install the `dev` dependencies for python linting and testing: + +=== "bash" + + ```bash + pip install .[dev] + ``` + +=== "zsh" + + ```zsh + pip install .\[dev\] + + ``` +For documentation generation, you can install the `docs` dependencies: + +=== "bash" + + ```bash + pip install .[docs] + ``` + +=== "zsh" + + ```zsh + pip install .\[docs\] + + ``` diff --git a/docs/hw/chimneys.md b/docs/hw/chimneys.md new file mode 100644 index 00000000..506dc826 --- /dev/null +++ b/docs/hw/chimneys.md @@ -0,0 +1,47 @@ +# Network interfaces (a.k.a. chimneys) + +Network interfaces (NIs) are essentially the gateway to the Network-on-Chip (NoC). Every endpoint in the system requires its own NI to issue and receive packets over the NoC. The main purpose of the NI is to translate the on-chip protocol (e.g. AXI) to the link-level protocol of the network. NIs are not trivial to implement since they need to adhere to all the rules of the on-chip protocol e.g. ordering, flow control, etc. However, the advantage of using NIs is that the rest of the network can be agnostic to the on-chip protocol, which results in simpler router microarchitecture and as well as better scalability. Currently, _FlooNoC_ was mainly designed to support AXI4 and ships with dedicated NIs. However, it is possible to extend _FlooNoC_ also with other protocols, by implementing custom NIs. + +??? quote "Why chimneys?" + The name of _FlooNoC_ is derived from the Floo Network of Harry Potter. In the books, the Floo Network is a magical network of fireplaces that allows witches and wizards to travel from one place to another. Therefore, the chimneys are the gateways to the Floo Network, which is why they are called chimneys. + +## AXI Network Interface + +_FlooNoC_ ships with two different AXI NIs: the `axi_chimney` and the `nw_chimney`, which mainly differ from the ports and links that are connected to them. As the name implies, the `axi_chimney` has a single AXI port and uses only `req`/`rsp` physical channels, while the `nw_chimney` has a narrow *and* a wide AXI port and additionally features a `wide` physical channel. In the following, we will describe the inner workings of the `axi_chimney` in more detail. The `nw_chimney` is very similar, with largely duplicate datapaths for the narrow and wide ports. + +### Ordering + +One of the main challenges of implementing an NI for the AXI protocol is the strict ordering requirement that is imposed by AXI. The NI interface needs to be able to guarantee that for transactions with the same `txnID` all responses arrive with the same order as how the request were injected into the network. By design, the _FlooNoC_ link-level protocol does not guarantee ordering. For instance, if one request is sent to destination `A` and second request to destination `B`, the response from `B` can arrive before the response from `A`. There are essentially to ways of solving this problem: _Reordering_ or _stalling_. + +#### Reordering + +Responses that arrive out-of-order are buffered in a reorder buffer (RoB) until they can be delivered in-order. This approach is more performant, since multiple requests can be issued to different endpoints at the same time. However, a RoB is costly in terms of area and needs to be limited in size. Furthermore, the NI still needs to ensure that all responses from the NoC can be handled, either by buffering them in the RoB or forwarding them to the on-chip protocol (if they are in order). Stalling the network is not an option, as this would inevitably lead to deadlocks. Therefore, the NI also needs to track or allocate space in the RoB and only inject new requests into the network if it can guarantee that the responses can be handled: + +#### Stalling + +Another way to solve the ordering problem is to simply stall the injection of new requests into the network if the NI cannot guarantee that the responses will arrive in order. This approach is very simple to implement, and has a very small overhead, but it can lead to significant performance degredation in some cases. Luckily, there are some optimizations that the AXI NIs apply, which reduce the number of stalls. First, transactions to the same destination are always guaranteed to arrive in order (assuming a static routing algorithm is used in side the network). This means that the NI can inject multiple requests into the network, while the destination stays the same. Second, the ordering requirement only applies to transactions with the same `txnID`. Therefore, downstream components can also use different IDs to avoid ordering issues. + +The AXI NIs of _FlooNoC_ offers both options, and there are different implementations that can be set with the `ChimneyCfg.RoBType` parameter. The following table shows the different options: + +| RoBType | Description | +|---------|-------------| +| `NoRoB` | No RoB, which stalls transactions of the same `txnID` going to different destinations until the previous transaction is completed. This is option is useful if the ordering of transactions is handled downstream, e.g. in the DMA by issuing AXI transactions with different `txnIDs`. The overhead of this RoB is very low, since it only requires counters for tracking the number of outstanding transactions of each `txnID`.| +| `NormalRoB` | The most performant but also most complex RoB, which supports reodering of responses. This reorder buffer retains the out-of-order nature of AXI transactions with different IDs. Supports multiple outstanding transactions and bursts | +| `SimpleRoB` | Simpler FIFO-like RoB, which does not support reordering of responses with the same AXI `txnID`. Transactions with different `txnIDs` are effectively serialized. Supports multiple outstanding transactions but currently does not support burst transactions. Mainly useful for B-responses which are single transactions. | + +The selection of the RoB type depends on the endpoints that are attached to it. For instance, cores with narrower AXI interfaces might are less costly to reorder with a RoB, while DMAs with wider interfaces and burst requests might be prohibitively expensive to reorder. `FlooNoC` gives the option to specify the RoB type and size in the `ChimneyCfg` parameter. In AXI, both read and write response exist, for which different RoBs can be selected. For instance, the `B` response is very small and the cost of reordering it is quite low, which might not be true for the `R` responses. + +### Routing + +Another task of the NI is also to create the header of the flit which contains all the information required to route a packet from source to destination. To do this, the NI needs to translate the request address to a destination ID, which can be done in two different ways: + +* Address Offset: The NI simply uses a fixed offset into the request address to determine the destination ID. For instance, assuming an node ID width of 3, and an address offset of 8, the address `0x0f00` would be translated to node ID `0x7`. This is the simplest way to route packets, but it is also the least flexible. For instance, if not all of the endpoints have the same address range size, a lot of address space might be wasted. For simpler systems, this might however be a good choice. The Address Offset method can be enabled by setting the `RouteCfg.IdAddrOffset`, respectively `RouteCfg.XYAddrOffsetX` and `RouteCfg.XYAddrOffsetX` in case of `XYRouting`. + +* Address Map: The other alternative is to use an address map to translate the request address to a node ID. This is usually in the form of a global System Address Map (SAM), which consists of a list of address ranges and the corresponding node IDs. To configure this, the `RouteCfg.UseIdTable` needs to be set and the System Address Map can be passed to the network interface with the `Sam` parameter (which also requires setting the `RouteCfg.NumSamRules` parameter). + +Source-based routing is handled a bit different, since the route instead of the destination ID needs to be included in the header. Calculating the route is done in two steps 1) the destination ID is computed the same way as for the node ID based routing and 2) the destination ID is used as an index into a routing table to determine the route. The routing table is passed to the network interface over the `route_table_i` port (which requires setting the `RouteCfg.NumRoutes` parameter). + +### AXI Transaction ID handling + +### Configuration +* spill registers diff --git a/docs/hw/commons.md b/docs/hw/commons.md new file mode 100644 index 00000000..5d110782 --- /dev/null +++ b/docs/hw/commons.md @@ -0,0 +1,3 @@ +# Common IPs + +*TODO* diff --git a/docs/hw/flits.md b/docs/hw/flits.md new file mode 100644 index 00000000..4cb9c996 --- /dev/null +++ b/docs/hw/flits.md @@ -0,0 +1,69 @@ +# Flits + +We start with the _flits_, also called flow control units, which is the smallest unit of data that is sent from node to another (e.g. from router to router, of network interface to router). Flits consists of two types of data: + +1. **Routing information**: Also called the header of the flit, this data is used by the routers to route the flit through the network. The header contains information such as the destination address, the source address, the flit type, etc. + +1. **Payload**: This is the actual data that is being sent from one node to another. Router do not look at the payload, they just forward it to the next hop. + +In traditional NoCs, the links have a fixed width (e.g. 32-bit). Usually, the payload and the information required for routing far exceeds this width. Therefore, the payload is split into multiple data flits and a header flit which encodes the routing information. Based on this information, routers in the network then know how to route the following data flits to the destination. + +In modern NoCs, this way of serializing payloads over the network is not very efficient anymore. With higher bandwidth requirements of the endpoints, the serialization becomes more and more a bottleneck, since the frequency of the links is limited. Further, serialization causes additional latency which is undesirable. Lastly, the overhead of the header flits is not negligible, especially when the payload is small. + +Therefore, In _FlooNoC_ and modern NoCs in general[^1], another approach is taken, which differs in two ways: + +[^1]: The [AMBA CHI](https://developer.arm.com/documentation/ihi0050/latest/) protocol also encodes the entire payload (cachelines in this case) in a single flit including all the information required for routing. + +1. **Flit width**: The width of the flits is not fixed anymore. Instead, the flits can be as wide as the payload to send the payload in a single cycle resp. in a single flit. + +1. **Parallel header**: Instead of sending the header before the payload, the header is sent in parallel to the payload. This way, the link utilization is not degraded by header flits. + +Below, we will discuss the header and the payload in more detail. + +## Header + +In _FlooNoC_ the header consists of the following fields: + +| Field | Type | Required by | Description | +| ----------- | --------------- | ---------- | --------------------- | +| `dst_id` | `dst_t` or `route_t` | Router | The destination ID of the flit. In the case of source-based routing, it encodes the entire route from source to destination. | +| `src_id` | `dst_t` | Chimney | The source ID of the flit. Used by the Chimney to set the `dst_id` for the response | +| `last` | `logic` | Router | Can be used by the Chimneys that a burst of flits is not interleaved with other flits from other endpoints. If not set the router performs wormhole routing i.e. it locks the direction until flit with the `last` bit set has been sent. | +| `axi_ch` | `axi_ch_e`[^2] | Chimney | Used by the Chimney to encode the type of packet e.g. which AXI channel | +| `rob_req` | `logic` | Chimney | Flag to signal that the flit might need to be reordered in the Chimney | +| `rob_idx` | `rob_idx_t` | Chimney | The index into the reorder buffer of the Chimney | +| `atop` | `logic` | Chimney | Flag to signal that the flit is an ATOP flit and can bypass the reodering logic. | + +!!! info "Additional fields" + + Additional fields can be added to the header if needed. The routers just ignore those fields and forward them to the next router/Chimney. + +!!! example "SystemVerilog macros" + + _FlooNoC_ provides System Verilog macros in `typedef.svh` to generate the header fields such as `FLOO_TYPEDEF_HDR_T`. + +[^2]: The type is arbitrary and depends on the type of Chimney used but it is usually an `enum`. For instance, the single-AXI chimney encodes only 5 channels in `axi_ch_e`, while the narrow-wide AXI chimney encodes 10 channels in `nw_ch_e`. This can also be extended. + +## Payload + +The payload itself can be any data that needs to be sent from one node to another. The payload is not interpreted by the routers, they just forward it to the next hop. The payload can be of any width. Usually, the payload consists of an AXI request or response of one of the 5 channels. + +## Types of flits + +The entire flit is constructed by concatenating the header and the payload. One can define many types of flits i.e. one for every payload. The only requirement is that the flit includes the following fields: + +| Field | Type | Description | +| ----------- | --------------- | --------------------- | +| `hdr` | `hdr_t` | The header of the flit, which is identical across the whole network | +| `payload` | `payload_t`[^3] | The payload of the flit, which can be of any width | +| `rsvd` | `logic[RsvdBits-1:0]` | Optional padding bits if the flit is smaller than the link width | + +[^3]: The payload type can be anything. For instance, sending an AXI AW is done by defining a `axi_aw_chan_t` struct for the payload type. + +!!! info "Additional fields" + + Again, additional fields can be added if needed. The only requirement is that the width of the flit matches exactly the width of the link. + +!!! example "SystemVerilog macros" + + _FlooNoC_ provides System Verilog macros in `typedef.svh` to generate the flits such as `FLOO_TYPEDEF_FLIT_T` for flits with the `rsvd` field and generic flits `FLOO_TYPEDEF_GENERIC_FLIT_T` without a `rsvd` field. diff --git a/docs/hw/links.md b/docs/hw/links.md new file mode 100644 index 00000000..002e28b1 --- /dev/null +++ b/docs/hw/links.md @@ -0,0 +1,106 @@ +# Channels + +Now that we established flits -- the smallest unit of data that is sent -- we can discuss how a flit is sent from one node to another. As we have explained in the [flits](flits.md) section, there usually exist multiple types of flits, which differ in the payload they carry. For instance, the payload can be an AXI request, an AXI response, or any other data that needs to be sent from one node to another. For multiple reasons, it makes sense to send these different types of flits over different "channels", which we will discuss in this section. + +## Why use multiple channels? + +Channels are a way to separate different types of flits. For instance, one channel can be used to send AXI requests, another channel can be used to send AXI responses, and a third channel can be used to send other types of data. This separation has multiple advantages: + +1. **Message-Level deadlocks**: If all flits are sent over a single channel, it could happen that message-level deadlocks are introduced. For instance, if node A sends a request to node B, and node B sends a request to node A, both nodes both nodes might need to wait for their response before accepting a new request, which can lead to a deadlock. By separating the request and response channel, we can ensure forward progress. + +1. **Latency**: Different types of flits might have different priorities. For instance, some messages are very latency-sensitive (e.g. synchronization messages), while others are much more latency-tolerant (e.g. bulk data transfers). By separating the channels, we can ensure that the congestion can be kept low on the latency-sensitive channel, which in turn reduces the latency of these messages. + +1. **Bandwidth**: Different types of flits might have different bandwidth requirements. For instance, the data widths of AXI can reach up to 1024 bit, and AXI additionally supports burst transfers. Using wide links is the natural way to increase the bandwidth of the channel. However, smaller flits like AXI write responses are only a fraction of the link width and would waste bandwidth if sent over a wide link. + +## Virtual vs. Physical channels + +There are essentially two different ways how to implement multiple channels: + +1. **Virtual channels**: Virtual channels are a way to multiplex multiple channels over a single physical channel. Virtual channel have the advantage that the physical channel can be used more efficiently, as it can be shared between multiple virtual channels. Moreover, message-level deadlocks can be prevented with virtual channels, as messages from different channels can be interleaved, resp. they can overtake each other. This is possible, since on the RX side of a virtual channel, every channel has its own buffers. So even if for instance the buffer for requests is full, responses can still be received. While virtual channels have its advantages, they also have some disadvantages. For instance, virtual channels require additional logic to multiplex and demultiplex the channels, which increases the complexity of the design. Furthermore, multiplexing onto a single physical channel limits the throughput of the channel. + +1. **Physical channels**: Physical channels on the other hand are _real_ physical channels in hardware. Effectively, physical channels result in multiple separate networks used to send different types of messages throught the network. The main advantage of physical channels is the throughpt of the channel, since it is not shared with other channels. Also, routers for physical channels can be streamlined, since they don't require multiplexing of virtual channels. One disadvantage of physical channels is that they require more routing resources, as each physical channel is implemented as a separate network. + +One of the main design principles of _FlooNoC_ is to use multiple physical channels instead of virtual channels. While the main drawback of physical channels is the increased routing resources, modern technologies come to rescue here. For instance, modern technologies usually can feature up to 20 metal layers and have routing resources of >10000 wires/mm that can be exploited to implement multiple physical channels. Not all of it is avaliable for routing of course, since some routing resources are used for cell connectivity and power distribution. However, the routing resources tend not to be the bottleneck in the design, especially not global wires on higher metal layers of the chip, which are primarly used for the routing of the physical links. + +!!! tip "Wires are cheap now" + + A very good source on this topic, which has also greatly influenced the use of physical channels during the development of _FlooNoC_ is the NOCS keynote [Reflections on 21 Years of NoCS](https://www.youtube.com/watch?v=Nk3oQm9NxcY) from Bill Dally, one of the pioneers in early NoC research. + +## _FlooNoC_ channels + +In _FlooNoC_, we use multiple physical channels to separate different types of traffic. The most basic form of _FlooNoC_ is to use two channels `req` and `rsp`, to send all request resp. responses. However, traffic in an SoC can be quite diverse, and comes with different requirements. For instance, synchronization messages are usually very small in the order of a few bytes, but are very latency-sensitive. On the other hand, bulk data transfers can be very large, but are usually more tolerant to latency, since they can be issued as multiple outstanding transactions. In some systems, this is the reason why mulitple AXI interfaces are used. A narrow one for configuration and synchronization messages and a wider one for bulk data transfers. In that case, _FlooNoC_ also featuers a `wide` channel to provide high bandwidth for bulk data transfers. + +## Channel Mapping + +### Single-AXI to `req`, `rsp` mapping + +If only a single AXI interface is used (e.g. with 32-bit address width and 64-bit data width), the AXI channels are mapped to the _FlooNoC_ channels as follows: + +| | `req` | `rsp` | primary payload | +| ----------------- | ---- | ---- | --- | +| `Aw` | :material-check: | - | `addr` (32-bit) | +| `Aw` | :material-check: | - | `addr` (32-bit) | +| `W` | :material-check: | - | `w_data` (64-bit) | +| `R` | - | :material-check: | `r_data` (64-bit) | +| `B` | - | :material-check: | `b_rsp` (2-bit) | + +The mapping is quite straightforward. Requests from AXI manager are sent over the `req` channel, while responses from AXI subordinates are sent over the `rsp` channel. Message-level deadlock are also avoided this way, since requests and responses are sent over different channels. + +## Narrow-Wide AXI to `req`, `rsp`, `wide` mapping + +In case two AXI interfaces are used, a narrow (e.g. 64-bit) and a wide one (e.g. 512-bit), the AXI channels are mapped to the _FlooNoC_ channels as follows: + +| | `req` | `rsp` | `wide` | primary payload | +| ----------------- | ---- | ---- | ---- | --- | +| `NarrowAw` | :material-check: | - | - | `addr` (32-bit) | +| `NarrowAr` | :material-check: | - | - | `addr` (32-bit) | +| `NarrowW` | :material-check: | - | - | `w_data` (64-bit) | +| `NarrowR` | - | :material-check: | - | `r_data` (64-bit) | +| `NarrowB` | - | :material-check: | - | `b_rsp` (2-bit) | +| `WideAw` | - | - | :material-check: | `addr` (32-bit) | +| `WideAr` | :material-check: | - | - | `addr` (32-bit) | +| `WideW` | - | - | :material-check: | `w_data` (512-bit) | +| `WideR` | - | - | :material-check: | `r_data` (512-bit) | +| `WideB` | - | :material-check: | - | `b_rsp` (2-bit) | + +In this case, the narrow AXI to `req`, `rsp` mapping is the same as in the single-AXI case. However, the wide AXI interface mapping is a different and requires some explanation. Unsurprisingly, the wide data channels `WideR` and `WideW` are mapped to the `wide` channel to make use of its high bandwidth. The AXI read request `WideAr` and the write response `WideB` are mapped to the `req` and `rsp` channel, respectively. Those are smaller messages and would underutilize the `wide` channel. The outlier here is the AXI write requests `WideAw`, which is mapped to the `wide` channel, eventhough it is a small message. The reason for this is related to the ordering of AXI transactions. + +??? info "AXI ordering for the curious" + + AXI supports out-of-order transactions by specifying transaction IDs (`txnID`). Transactions with the same `txnID` need to be ordered with respect to each other i.e. they cannot overtake each other. Transactions with different `txnID` however are free to do so. The `txnID` is specified in the initial requests and the corresponding read and write response also carries the same `txnID`. However, the write data is a bit different in this regard. The write data `W` does not feature any `txnID` and needs to be sent (and eventually arrive at the AXI subordinate) in the same order as the write requests `Aw`. This also needs to be guaranteed in systems with multiple AXI managers that send write requests to the same AXI subordinate. If the `Aw` and `W` are sent over different channels, it might be that the order of them is not preserved since those differnent channels might have different congestion levels. To avoid this, the `WideAw` and `WideW` are sent over the same channel, which is the `wide` channel in this case. Furthermore, it also needs to be guaranteed that `WideW` payloads from different AXI requesters are not interleaved in the network, since they cannot be distinguished when arriving at the destination (which would also very likely require large reorder buffers). The non-interleaving needs to be guaranteed by the routers as well, which will be discussed later in the [routers](routers.md) section. + + +_FlooNoC_ uses `unions` to represent the different types of flits that are sent over the same physical channel. For instance, the `req` channel for a single-AXI configuration is defined as follows: + +```verilog +typedef union packed { + floo_aw_flit_t axi_aw; + floo_w_flit_t axi_w; + floo_ar_flit_t axi_ar; + floo_generic_flit_t generic; +} floo_req_chan_t; +``` + +A `union` essentially allows to represent multiple types of data in the same number of bits. This is also why `rsvd` bits are used in the flits, to ensure that the flits sent over a channel all have the same size. The `generic` is not meant to represent a flit with an actual payload, but can be used to decode the type of flit from its header. + +!!! example "SystemVerilog Macros" + Similar to the flits, _FlooNoC_ provides System Verilog macros in `typedef.svh` to generate the channel types such as `FLOO_TYPEDEF_AXI_CHAN_ALL` for a single-AXI configuration and `FLOO_TYPEDEF_NW_CHAN_ALL` for a narrow-wide AXI configuration. + + +## Links + +The links itself wraps a channel and additionally handles the flow control needed to send data from one node to another. _FlooNoC_ primarily uses valid-ready handshaking flow control, but also has some support for credit-based flow control (see routers section for more information). The link then looks as follows: + +```verilog + typedef struct packed { + logic valid; + logic ready; + floo_req_chan_t req; + } floo_req_t; +``` + +!!! info "Bidirectional links" + Currently, _FlooNoC_ only supports bidirectional links. This is why both `valid` and `ready` are encoded in the same link, eventhough they are separate from each other (i.e. the `ready` is an RX signal, while the `valid` is a TX signal). + +!!! example "SystemVerilog Macros" + Again, _FlooNoC_ provides System Verilog macros in `typedef.svh` to generate the flit types. For instance, `FLOO_TYPEDEF_AXI_LINK_ALL` for a single-AXI configuration and `FLOO_TYPEDEF_NW_LINK_ALL` for a narrow-wide AXI configuration. diff --git a/docs/hw/overview.md b/docs/hw/overview.md new file mode 100644 index 00000000..85544bc3 --- /dev/null +++ b/docs/hw/overview.md @@ -0,0 +1,19 @@ +# Overview of the Hardware IPs + +_FlooNoC_ is a collection of Network-on-Chip (NoC) IPs written in SystemVerilog that can used to assemble an NoC. In system architecture, there are a myriad of different considerations that go into the implementation of the on-chip network. From the topology of the network, the routing algorithm, flow-control, the use of virtual or physical channels, etc. This is why our goal was to make the _FlooNoC_ IPs as modular, configurable and extendible as possible, so that they can be easily integrated into any system. + +However, this also means that the hardware IPs are heavily parametrizable and the user has to make a lot of decisions when configuring the _FlooNoC_ IPs. This is what this documentation aims to help with. It will guide through all the available IPs, explain their architecture, and show how they need to be configured and what the trade-offs are. The documentation is structured as follows: + +1. **[Links](links.md)**: This section will explain the custom link-level protocol, which is used to connect the routers and network interfaces in the NoC. + +1. **[Routing Algorithms](route_algos.md)**: This section will explain the different routing algorithms that are available in _FlooNoC_ and how they can be configured. + +1. **[Network Interfaces](chimneys.md)**: This section will explain the different network interfaces which are used to convert to the custom link-level protocol of _FlooNoC_. + +1. **[Routers](routers.md)**: This section will explain the routers routers that are available in _FlooNoC_ and how they can be configured. + +1. **[Common IPs](commons.md)**: Apart from the two essential IPs, routers and network interfaces, there are also some common IPs that can be used to extend the functionality of the NoC. This section will explain these IPs. + +1. **[Verification IPs](vips.md)**: This section will explain the verification IPs that are available in _FlooNoC_ and how they can be used to verify the NoC. + +1. **[Tips & Tricks](tips.md)**: This section will give some tips and tricks on how to use the _FlooNoC_ IPs. diff --git a/docs/hw/route_algos.md b/docs/hw/route_algos.md new file mode 100644 index 00000000..9cf510c7 --- /dev/null +++ b/docs/hw/route_algos.md @@ -0,0 +1,79 @@ +# Routing Algorithms + +One of the main design principles of _FlooNoC_ is that it is flexible and can support multiple routing algorithms as well as arbitrary topologies. Currently, _FlooNoC_ supports the following routing algorithms: + +1. **Dimension-ordered Routing (DOR)**: Also known as XY-Routing and arguably the most popular routingn algorithm used in 2D mesh networks, due to its simple implementation and guarantee of deadlock freedom. + +1. **Source-based routing**: A routing algorithm where the source specifies the entire route to the destination. + +1. **Table-based routing**: A routing algorithm where the selection of port is based on a table that is provided to the router. + +All of those routing algorithms are static respectively deterministic. While dynanmic routing algorithms might feature better performance since it can adapt to changing network conditions, they are also more complex to implement and might introduce deadlocks. Furthermore, _FlooNoC_ uses the deterministic routing assumption of the network to guarante the correct ordering of AXI transactions. For instance, _FlooNoC_ relies on the fact that flits from the same source and channel to the same destination remain ordered, which is not given in dynamic routing algorithms. + +## Dimension-ordered (DOR) + +Dimension-ordered routing is a simple routing algorithm that routes flits based on XY-coordinates, which is why it is commonly used in 2D mesh networks. In dimension ordered routing, a flit is always routed in one dimension and then in the other. Since this routing cannot introduce any cycles, it is deadlock-free by design. The implementation of DOR is also very simple, as it only requires the current and destination coordinates of the flit. Each router knows its own XY coordinates and compares them to the destination coordinates of the flit. The routing algorithm then is the following: + +$$ +Port = \begin{cases} +East & id_{dst, x} > id_{router, x} \\ +West & id_{dst, x} < id_{router, x} \\ +North & id_{dst, x} = id_{router, x} \land id_{dst, y} > id_{router, y} \\ +South & id_{dst, x} = id_{router, x} \land id_{dst, y} < id_{router, y} \\ +Eject & id_{dst, x} = id_{router, x} \land id_{dst, y} = id_{router, y} +\end{cases} +$$ + +Meaning, the flits is routed to either the east or west until it reaches the correct X-coordinate, after which it is routed to the north or south until. If both coordinates match, the flit is ejected from the network i.e. it is sent to (one of the) local port(s) of the router. + +### Advantages + +The DOR routing algorithm is very simple but effective and results in very low complexity in the hardware. Furthermore, it is deadlock-free by design since it cannot introduce any cycles. Also, XY-routing allows for some optimization in the router design. Since a flit is always routed first in X and then in Y, some connections in the router are illegal and can be disabled to reduce the number of connections in the router. For instance, the connection from north to east or west is not possible as this would imply that the flit was routed in the Y-dimension before the X-dimension. + +### Disadvantages + +The main disadvantage of DOR routing is that it only works in 2D meshes. Also, there are some corner cases where DOR routing can create problems. For instance, if nodes are attached to the boundary of the mesh, a flit entering from the north boundary cannot reach the east boundary, since it would have to change X and Y direction multiple times. + +## Source-based Routing + +Source-based routing is another simple routing algorithm where the entire route to the destination is specified by node which injects the flit into the network. The route is encoded in the header of the flit as an array of ports that each router should take. The size of the route encoding depends on the diameter of the network (the maximum number of hops) as well as the router radix (number of router ports). For instance, a route might be encoded like this in a 4x4 2D mesh network: + +```verilog + route_t route = '{3'b0, 3'b1, 3'b2, 3'b3, 3'b4, 3'b5, 3'b6}; +``` + +A router usually has 5 ports (4 for the cardinal directions and one local port), which can be encoded in 3 bits. Further, the maximum number of hops in a router is 7 (including the routers where the flit is injected and ejected), which results in a route encoding of 21 bits. This route encoding is part of the flit header and is checked by each router. + +??? example "Flit header differences" + The header of a flit is different for source-based routing compared to the other routing algorithms. Instead of encoding the destination id (`dst_id`) as a node ID (of type `id_t`), the destination id is encoded as a route (`route_t`). The source id (`src_id`) is still encoded as a node ID, since the source node generally does not know the route back to itself from the destination. Instead it provides the `src_id`, which can be translated back to a route by the destination node. + + +The implementation of this routing algorithm is also very simple, since every router _consumes_ a port from the route encoding, which means it simply shifts the route encoding by the number of bits that is required to encode the number of possible ports. This way, a router does not neet to be aware of how many hops a flit has already passed, since it can simply look at the first bits of the route encoding to determine the next port. + +### Advantages + +The main advantage of source-based routing is that it is very flexible and can be used in arbitrary topologies, that go beyond 2D meshes. The routes can also be optimized for instance to reduce congestion or to minimize the number of hops. Theoretically, source-based routing can also be dynamic, since the source can change the route encoding based on the network conditions. However, as mentioned before, _FlooNoC_ currently does not support dynamic routing algorithms. + +### Disadvantages + +The main disadvantage of source-based routing is that the bits required for encoding the route grows with the network diameter and at some point it becomes infeasible to encode the route in the flit header. Also, source-based routing is not inherently deadlock-free, if the routes are not carefully chosen. Lastly, the route encodings need to be provided to the source respectively the network interface, which can become quite large, since every destination requires its own route encoding. + +## Table-based Routing + +Table-based routing shifts the routing computation to the routers themselves. Each router has a table that specifies the output port for each destination. Instead of using actual tables, it is also possible to use address decoders which can reduce the number of entries in the table, since it allows to specify a range of destinations that are routed to the same port. An instance of such a routing table could look like the following: + +```verilog + localparam router_rule_t [NumRules-1:0] RouterTable = '{ + '{idx: 1, start_addr: 0, end_addr: 2}, // -> port 1 for destination 0, 1 + '{idx: 2, start_addr: 2, end_addr: 3}, // -> port 2 for destination 2 + '{idx: 3, start_addr: 3, end_addr: 10} // -> port 3 for destination 3 to 9 + }; +``` + +where `idx` is the port number and `start_addr` and `end_addr` is the range of destination node IDs that are routed to the port. + +### Advantages +Similar to source-routing, table-based routing can be used for any kind of topology and the routes respectively the routing tables can be optimized to avoid congestion etc., Also, table-based routing can be dynamic, since the routing tables could be updated dynamically (which is not supported by _FlooNoC_). + +### Disadvantages +Table-based routing has a similar problem as source-based routing, since the router tables grow with the number of destinations. Also, table-based routing is not inherently deadlock-free, if the routing tables are not carefully chosen. Lastly, the routing tables need to be provided to the routers, which can become quite large, since every destination requires its own routing table. diff --git a/docs/hw/routers.md b/docs/hw/routers.md new file mode 100644 index 00000000..ff4f3e83 --- /dev/null +++ b/docs/hw/routers.md @@ -0,0 +1,3 @@ +# Routers + +*TODO* diff --git a/docs/hw/tips.md b/docs/hw/tips.md new file mode 100644 index 00000000..a0c1a693 --- /dev/null +++ b/docs/hw/tips.md @@ -0,0 +1 @@ +# Tips & Tricks diff --git a/docs/hw/vips.md b/docs/hw/vips.md new file mode 100644 index 00000000..ced2cfd7 --- /dev/null +++ b/docs/hw/vips.md @@ -0,0 +1,3 @@ +# Verification IPs (VIPs) of _FlooNoC_ + +*TODO* diff --git a/docs/img/floo_noc_favicon_logo.png b/docs/img/floo_noc_favicon_logo.png new file mode 100644 index 00000000..be19c455 Binary files /dev/null and b/docs/img/floo_noc_favicon_logo.png differ diff --git a/docs/img/floo_noc_favicon_logo.svg b/docs/img/floo_noc_favicon_logo.svg new file mode 100644 index 00000000..23a7eb85 --- /dev/null +++ b/docs/img/floo_noc_favicon_logo.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/docs/img/floo_noc_material_logo.png b/docs/img/floo_noc_material_logo.png new file mode 100644 index 00000000..85b0c540 Binary files /dev/null and b/docs/img/floo_noc_material_logo.png differ diff --git a/docs/img/floo_noc_material_logo.svg b/docs/img/floo_noc_material_logo.svg new file mode 100644 index 00000000..0090fc82 --- /dev/null +++ b/docs/img/floo_noc_material_logo.svg @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..986fd92c --- /dev/null +++ b/docs/index.md @@ -0,0 +1,57 @@ +# FlooNoC: A Fast, Low-Overhead On-chip Network + +_FlooNoC_, is a Network-on-Chip (NoC) research project, which is part of the [PULP (Parallel Ultra-Low Power) Platform](https://pulp-platform.org/). The main idea behind _FlooNoC_ is to provide a scalable high-performance NoC for non-coherent systems. _FlooNoC_ was mainly designed to interface with [AXI4+ATOPs](https://github.com/pulp-platform/axi/tree/master), but can easily be extended to other On-Chip protocols. _FlooNoC_ already provides network interface IPs (named chimneys) for AXI4 protocol, which converts to a custom-link level protocol that provides significantly better scalability than AXI4. _FlooNoC_ also includes protocol-agnostic routers based on the custom link-level protocol to transport payloads. Finally, _FlooNoC_ also include additional NoC components to assemble a complete NoC in a modular fashion. _FlooNoC_ is also highly flexible and supports a wide variety of topologies and routing algorithms. A Network generation framework called _FlooGen_ makes it possible to easily generate entire networks based on a simple configuration file. + +## Quick Links + +
+ +- :material-fast-forward:{ .lg .middle } __Setup & Installation__ + + --- + + Install Bender for HW IPs and python dependencies for _FlooGen_ + + [:octicons-arrow-right-24: Getting started](getting_started.md) + +- :fontawesome-solid-microchip:{ .lg .middle } __Hardware IPs__ + + --- + + Check out the documentation of _FlooNoC_ hardware IPs. + + [:octicons-arrow-right-24: Hardware IPs](hw/overview.md) + +- :material-magic-staff:{ .lg .middle } __Network Generation__ + + --- + + Learn how to generate a _FlooNoC_ network using _FlooGen_ + + [:octicons-arrow-right-24: FlooGen](floogen/overview.md) + +- :material-scale-balance:{ .lg .middle } __License__ + + --- + + _FlooNoC_ is available open-source on [GitHub](https://github.com/pulp-platform/FlooNoC) under permissive licenses. + + [:octicons-arrow-right-24: License](license.md) + +- :material-bookshelf:{ .lg .middle } __Publication__ + + --- + + Read the publication of _FlooNoC_. + + [:octicons-arrow-right-24: Publication](https://arxiv.org/abs/2305.08562) + +- :material-file-document:{ .lg .middle } __Changelog__ + + --- + + Check out what has changed in the latest version of _FlooNoC_. + + [:octicons-arrow-right-24: Changelog](changelog.md) + +
diff --git a/docs/javascripts/mathjax.js b/docs/javascripts/mathjax.js new file mode 100644 index 00000000..7e48906a --- /dev/null +++ b/docs/javascripts/mathjax.js @@ -0,0 +1,19 @@ +window.MathJax = { + tex: { + inlineMath: [["\\(", "\\)"]], + displayMath: [["\\[", "\\]"]], + processEscapes: true, + processEnvironments: true + }, + options: { + ignoreHtmlClass: ".*|", + processHtmlClass: "arithmatex" + } +}; + +document$.subscribe(() => { + MathJax.startup.output.clearCache() + MathJax.typesetClear() + MathJax.texReset() + MathJax.typesetPromise() +}) diff --git a/docs/license.md b/docs/license.md new file mode 100644 index 00000000..6ef3f5a9 --- /dev/null +++ b/docs/license.md @@ -0,0 +1,3 @@ +# License + +All code checked into this repository is made available under a permissive license. All software sources of _FlooGen_ under `floogen` are licensed under the [Apache License 2.0](Apache-License.md), and all hardware sources in the `hw` folder are licensed under the [Solderpad Hardware License 0.51](SHL-License.md). diff --git a/docs/repository_structure.md b/docs/repository_structure.md new file mode 100644 index 00000000..6de42ace --- /dev/null +++ b/docs/repository_structure.md @@ -0,0 +1,23 @@ +# Repository Structure and Contents + +This document describes the structure of the repository and the contents of the directories. + +## The `hw` hardware directory + +The `hw` directory contains all the hardware-related files for all the SystemVerilog IPs. The directory is structured as follows: + +- `*.sv`: SystemVerilog packages and modules for the IPs. +- `test`: Verification IPs (VIPs) such as monitors, random initiators for the testbenches. +- `tb`: Testbenches for the IPs. + +## The `floogen` _FlooGen_ directory + +The `floogen` directory contains the Python framework for _FlooGen_ to generate complete _FlooNoC_ networks based on a simple configuration file. The directory is structured as follows: + +- `examples`: A couple of example configuration files. +- `model`: The python models for routers, network interfaces and endpoints that are used by _FlooGen_. +- `templates`: Mako templates for the generation of the SystemVerilog files. +- `tests`: Unit tests for the _FlooGen_ framework. +- `floo_gen.py`: The main script for _FlooGen_. +- `config_parser.py`: The configuration parser for _FlooGen_. +- `utils.py`: Various utility functions for _FlooGen_. diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 00000000..2ea440b2 --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,9 @@ +/* Copyright 2024 ETH Zurich and University of Bologna. */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +:root { + --md-primary-fg-color: #02793C; + --md-primary-fg-color--light: #21B42A; + --md-primary-fg-color--dark: #05422B; +} diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000..75a86ce7 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,99 @@ +# Copyright 2020 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +site_name: FlooNoC + +extra_css: + - stylesheets/extra.css + +extra_javascript: + - javascripts/mathjax.js + - https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js + +theme: + logo: img/floo_noc_material_logo.png + favicon: img/floo_noc_favicon_logo.png + name: material + palette: + + # Palette toggle for light mode + - scheme: default + media: "(prefers-color-scheme: light)" + primary: custom + accent: light green + toggle: + icon: material/weather-sunny + name: Switch to dark mode + + # Palette toggle for dark mode + - scheme: slate + media: "(prefers-color-scheme: dark)" + primary: custom + accent: light green + toggle: + icon: material/weather-night + name: Switch to light mode + icon: + repo: fontawesome/brands/github + features: + - navigation.tabs + - navigation.tabs.sticky + - navigation.instant + - navigation.tracking + - navigation.indexes + - navigation.footer + - content.code.copy + +repo_url: https://github.com/pulp-platform/FlooNoC +repo_name: pulp-platform/FlooNoC +site_url: https://pulp-platform.github.io/FlooNoC + +plugins: + - social: + - git-revision-date-localized: + enable_creation_date: true + +markdown_extensions: + - admonition + - attr_list + - footnotes + - md_in_html + - pymdownx.arithmatex: + generic: true + - pymdownx.details + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true + - tables + +nav: +- Home: + - index.md + - Repository Structure: repository_structure.md + - License: license.md + - Contributing: CONTRIBUTING.md +- Getting Started: getting_started.md +- Hardware IPs: + - Overview: hw/overview.md + - Flits: hw/flits.md + - Channels & Links: hw/links.md + - Routing Algorithms: hw/route_algos.md + - Network Interfaces: hw/chimneys.md + - Router: hw/routers.md + - Common IPs: hw/commons.md + - Verification IPs: hw/vips.md + - Tips & Tricks: hw/tips.md +- FlooGen: + - Overview: floogen/overview.md + - Routing & Topologies: floogen/routing.md + - Protocols: floogen/protocols.md + - Endpoints: floogen/endpoints.md + - Routers: floogen/routers.md + - Connections: floogen/connections.md + - CLI: floogen/cli.md + - Known Issues: floogen/known_issues.md +- Changelog: changelog.md diff --git a/pyproject.toml b/pyproject.toml index 0e4df9ff..9b901609 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,14 +23,27 @@ dependencies = [ "matplotlib", "mako", "ruamel.yaml", - "hjson", - "jsonref", "click", "pylint", "pytest", "pygame" ] +[project.optional-dependencies] +docs = [ + "mkdocs", + "mkdocs-material", + "pillow", + "cairosvg", + "mkdocs-git-revision-date-localized-plugin", + "mkdocs-git-committers-plugin-2" +] +dev = [ + "black", + "pylint", + "pytest" +] + [build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta"