diff --git a/docs/getting_started.md b/docs/getting_started.md index 0b43fd8..586da1f 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -5,7 +5,9 @@ --- # Getting Started -This section will walk through the steps of setting up a suitable build environment for Nexus, compiling an example design, and running it on the model and RTL. +This section will walk through the steps of setting up a suitable build +environment for Nexus, compiling an example design, and running it on the model +and RTL. ## Setup You will need a few tools to be installed on your system: @@ -15,27 +17,32 @@ You will need a few tools to be installed on your system: * [yosys](https://github.com/YosysHQ/yosys); * GNU Make. -Once this baseline is available, you will also need to install a number of Python packages - you may wish to do this in a virtual environment. The easiest way to do this is to use the `requirements.txt` file: +Once this baseline is available, you will also need to install a number of +Python packages - you may wish to do this in a virtual environment. The easiest +way to do this is to use the `requirements.txt` file: ```bash -$> python3 -m virtualenv venv +$> python3 -m venv venv $> . ./venv/bin/activate $> pip install -r requirements.txt ``` -As a future improvement, a [pyenv](https://github.com/pyenv/pyenv) configuration could be provided to simplify this setup process. - ## Running Synthesis -The first step is to get a JSON export of a generic mapped synthesised design from yosys. Here we will use `tests/multilayer_8bit` which is an example design containing two 8-bit counters which feed an 8-bit adder with overflow which drives the output signals. +The first step is to get a JSON export of a generic mapped synthesised design +from yosys. Here we will use `tests/multilayer_8bit` which is an example design +containing two 8-bit counters which feed an 8-bit adder with overflow which +drives the output signals. ```bash $> cd tests/multilayer_8bit $> make synth ``` -This should run yosys and produce a file `work/Top.json` which contains the synthesised design. The steps performed in this synthesis operation are shown below (also visible in `work/yosys.do`): +This should run yosys and produce a file `work/Top.json` which contains the +synthesised design. The steps performed in this synthesis operation are shown +below (also visible in `work/yosys.do`): -``` +```tcl read -incdir .../nexus/tests/multilayer_8bit/rtl; read -sv .../nexus/tests/multilayer_8bit/rtl/adder.v; read -sv .../nexus/tests/multilayer_8bit/rtl/counter.v; @@ -49,27 +56,79 @@ opt; write_json -aig Top.json; ``` -## Compiling onto the Mesh -The next step is to run `nxcompile` to produce a design compatible with the Nexus mesh. In this example a 6x6 (36 node) mesh is used. Starting from the root of the `nexus` directory: +## Compiling for Nexus +The next step is to run `nxcompile` to produce a design compatible with Nexus. +In this example a 6x6 (36 node) mesh is used. Starting from the root of the +`nexus` directory: ```bash -$> ./bin/nxcompile tests/multilayer_8bit/work/Top.json Top nx_top.json --rows 6 --cols 6 +$> ./bin/nxcompile tests/multilayer_8bit/work/Top.json Top nx_top.json --rows 3 --cols 3 ``` The arguments given to `nxcompile` are: - * `tests/multilayer_8bit/work/Top.json` - this is the output JSON file from yosys containing the synthesised design; + * `tests/multilayer_8bit/work/Top.json` - this is the output JSON file from + yosys containing the synthesised design; * `Top` - name of the top level of the design to compile; * `nx_top.json` - name of the output file containing the compiled design; - * `--rows 6` - number of rows in the target mesh; - * `--cols 6` - number of columns in the target mesh. + * `--rows 3` - number of rows in the target mesh; + * `--cols 3` - number of columns in the target mesh. + +This will take a second or two to run, and will print out mesh utilisation +reports when it completes. -This will take a second or two to run, and will print out mesh utilisation reports when it completes. +``` +Summary Usage: + + 0 1 2 3 4 5 +----------------------------------------- + 0 | 0.375 0.938 0.250 0.500 0.562 0.094 + 1 | 0.000 0.000 0.000 0.000 0.000 0.000 + 2 | 0.000 0.000 0.000 0.000 0.000 0.000 + 3 | 0.000 0.000 0.000 0.000 0.000 0.000 + 4 | 0.000 0.000 0.000 0.000 0.000 0.000 + 5 | 0.000 0.000 0.000 0.000 0.000 0.000 +``` -If you take a look at the compiled design in `nx_top.json`, you will see a section for each node including the instructions to execute as well as the input and output configurations. +If you take a look at the compiled design in `nx_top.json`, you will see a +section for each node including the instructions to execute as well as the +output messages. + +```json +{ + ... + "nodes": [ + { + "row": 0, + "column": 0, + "instructions": [ + 254017537, + 255066115, + 1057239045, + ... + ], + "loopback": 848, + "outputs": [ + [ + { + "row": 0, + "column": 3, + "index": 6, + "is_seq": false + } + ], + ... + ] + }, + ... + ] +} +``` ## Disassembling the Design -This step is not usually required, but is useful for debugging. Here we'll use `nxdisasm` to parse the compiler output and produce instruction listings as well a Verilog version of the translated design: +This step is not usually required, but is useful for debugging. Here we'll use +`nxdisasm` to parse the compiler output and produce instruction listings as well +a Verilog version of the translated design: ```bash $> ./bin/nxdisasm nx_top.json --listing listing.txt --verilog nx_top.v @@ -78,7 +137,8 @@ $> ./bin/nxdisasm nx_top.json --listing listing.txt --verilog nx_top.v The arguments given to `nxdisasm` are: * `nx_top.json` - this is the output from the compiler; - * `--listing listing.txt` - request a dump of the instruction listings for every node into `listing.txt`; + * `--listing listing.txt` - request a dump of the instruction listings for every + node into `listing.txt`; * `--verilog nx_top.v` - translate the compiled design back into Verilog. The instruction listing will look something like: @@ -102,15 +162,8 @@ While the translated Verilog will start with something similar to: module Top ( input wire clk , input wire rst - , output wire Top_sum_1 - , output wire Top_sum_0 - , output wire Top_sum_6 - , output wire Top_sum_4 - , output wire Top_overflow_0 - , output wire Top_sum_2 - , output wire Top_sum_7 - , output wire Top_sum_3 - , output wire Top_sum_5 + , output wire [7:0] sum + , output wire [0:0] overflow ); // ============================================================================= @@ -118,59 +171,59 @@ module Top ( // ============================================================================= // Input Construction -reg r0_c0_input_0; +wire r0_c0_input_0 = r0_c1_instr_51; reg r0_c0_input_1; ... ``` ## Simulating Using the Model -A compiled design can be simulated using `nxmodel` which provides a golden reference for the RTL behaviour: +A compiled design can be simulated using `nxmodel` which provides a golden +reference for the RTL behaviour: ```bash -$> ./bin/nxmodel nx_top.json --rows 6 --cols 6 --cycles 100 --vcd test.vcd -00000415 nxmodel : Checking all instructions loaded correctly -00000415 nxmodel : All OK! -00000415 nxmodel : Generating tick 1 -00000415 nxmodel : Captured 0 outputs from tick 0 -... -# ============================================================================== -# Simulation Statistics -# ============================================================================== -# -# Simulated Cycles : 100 -# Elapsed Clock Ticks: 4678 -# Elapsed Real Time : 5.35 seconds -# Cycles/second : 18.71 -# -# ============================================================================== +$> ./bin/nxmodel nx_top.json --rows 3 --columns 3 --cycles 100 --vcd test.vcd +[NXMesh] Running for 100 cycles +[Nexus] Achieved frequency of 40309 Hz +[Nexus] Writing VCD to .../nexus/test.vcd ``` The arguments here are: * `nx_top.json` - this is the output from the compiler; - * `--rows 6` - tells the model how many rows should be in the mesh; - * `--cols 6` - tells the model how many columns should be in the mesh; + * `--rows 3` - tells the model how many rows should be in the mesh; + * `--columns 3` - tells the model how many columns should be in the mesh; * `--cycles 100` - how many cycles the simulation should run for; - * `--vcd test.vcd` - captures the mesh state and outputs into a VCD as the simulation runs. + * `--vcd test.vcd` - captures the mesh state and outputs into a VCD as the + simulation runs. A tool like GTKWave can be used to view the captured VCD: ![Model VCD](./images/model_vcd.png) ## Running on the Real RTL -The most exciting part of course is running the compiled design on the real Nexus mesh RTL. The `hardware` folder contains the full RTL of the design, along with a number of [cocotb](https://github.com/cocotb/cocotb) testbenches for verifying the behaviour of each block. - -The bench we're interested in here is `hardware/testbench/nexus` - which can cosimulate the entire Nexus mesh against the behaviour of `nxmodel` cross checking all signal state after each simulated cycle. The `mission_mode` testcase (defined in `hardware/testbench/nexus/testbench/testcases/mission.py`) is already setup to do this, and will run the design contained in `hardware/testbench/nexus/testbench/data/design.json`. +The most exciting part of course is running the compiled design on the real +Nexus mesh RTL. The `hardware` folder contains the full RTL of the design, along +with a number of [cocotb](https://github.com/cocotb/cocotb) testbenches for +verifying the behaviour of each block. + +The bench we're interested in here is `hardware/testbenches/top/nexus` - which +can cosimulate the entire Nexus mesh against the behaviour of `nxmodel` cross +checking all signal state after each simulated cycle. The `mission_mode` +testcase (defined in `hardware/testbench/nexus/testbench/testcases/mission.py`) +is already setup to do this, and will run the design contained in +`hardware/testbench/nexus/testbench/data/design.json`. ```bash -$> cp nx_top.json hardware/testbench/nexus/testbench/data/design.json -$> cd hardware/testbench/nexus -$> make run TESTCASE=mission_mode EN_WAVES=yes +$> cp nx_top.json hardware/testbenches/top/nexus/testbench/data/design.json +$> cd hardware/testbenches/top/nexus +$> make TESTCASE=mission_mode EN_WAVES=yes ``` -This will run the simulation for 256 cycles, checking against the golden reference model after every cycle and reporting any failures that occur. Using `EN_WAVES=yes` will enable wave capture of the mesh as it runs. +This will run the simulation for 300 cycles, checking against the golden +reference model after every cycle and reporting any failures that occur. Using +`EN_WAVES=yes` will enable LXT wave capture of the mesh as it runs. -Once the simulation completes, you can use GTKWave to view the LXT wave file `sim.lxt`: +Once the simulation completes, you can use GTKWave to view the LXT waveform: ```bash $> gtkwave sim.lxt nexus.gtkw diff --git a/docs/images/model_vcd.png b/docs/images/model_vcd.png index 99c5055..c09aff3 100644 Binary files a/docs/images/model_vcd.png and b/docs/images/model_vcd.png differ diff --git a/docs/images/rtl_vcd.png b/docs/images/rtl_vcd.png index a9b4d05..f2578ad 100644 Binary files a/docs/images/rtl_vcd.png and b/docs/images/rtl_vcd.png differ