Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,22 @@ The project implements a simple message processing pipeline that parses fixed-wi

```mermaid
flowchart LR
A(input) --> |32-bit input message| B(message parser)
B --> |message type| C(message filter)
B --> |values| C

B --> |values| D(Output Formatter)
C --> |accepted/rejected| D
D --> |values| E(output)
D --> |reject reason| E
A("32-bit message<br/>input_valid") --> B["input register<br/>(clk, reset)"]
B --> C["parser / filter / formatter"]
C --> D["output register<br/>(clk, reset)"]
D --> E("value_a / value_b<br/>reject_reason<br/>output_valid")
```

For flowchart with module-level detail, see [`rtl/README.md`](rtl/README.md).

## Current Features

- 32-bit message parser
- Simple parameterised message filter
- Output formatter for accepted/rejected messages
- Top-level RTL pipeline
- Original Verilog testbench
- `cocotb` tests using fixed input cases
- Python reference model for checking expected behaviour
- Synchronous Verilog message-processing pipeline
- 32-bit parser, parameterised filter, and output formatter
- `cocotb` verification with fixed and randomised test cases
- Python reference model for expected behaviour
- GitHub Actions CI for automated tests
- Vivado synthesis and timing reports

## Message Format

Expand All @@ -42,14 +39,18 @@ flowchart LR

The project currently includes fixed-case and randomised cocotb tests. The cocotb randomised tests run automatically using GitHub Actions.

For cocotb setup and test-running instructions, see [`tb/cocotb/README.md`](tb/cocotb/README.md).

| File | Purpose |
| -------------------------- | ------------------------------------------------------------- |
| `test_direct_cases.py` | Fixed input cases with manually specified expected outputs |
| `test_reference_cases.py` | Fixed input cases checked against Python reference model |
| `test_random_reference.py` | Randomised input cases checked against Python reference model |
| `reference_model.py` | Python software model of the expected RTL behaviour |

Example Output:
Vivado synthesis and timing reports are included in [`docs/synthesis.md`](docs/synthesis.md).

Example `cocotb` Output:

```text
1000000.00ns INFO test 1000000 tests ran successfully...
Expand All @@ -62,5 +63,4 @@ Example Output:

## Status

Working simple RTL pipeline with Verilog and cocotb verification.
A Python reference model is used to check fixed and randomised test cases against expected behaviour.
Synchronous RTL pipeline is implemented and verified with fixed and randomised cocotb tests against a Python reference model. Vivado synthesis and post-synthesis timing checks have also been run for the current design.
1 change: 1 addition & 0 deletions constraints/constraints.xdc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
create_clock -period 10.000 -name clk [get_ports clk]
18 changes: 18 additions & 0 deletions docs/synthesis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Synthesis

Vivado synthesis was run on the RTL pipeline targeting the Artix-7 XC7A35T device which is used on the Basys 3 board.

## Summary

| Item | Result |
| ----------------- | -------- |
| LUTs | 25 |
| Flip-Flops | 40 |
| Latches | 0 |
| Worst Setup Slack | 6.909 ns |
| Worst Hold Slack | 0.179 ns |

## Full Reports

- [`utilization_report.txt`](./utilization_report.txt)
- [`timing_summary.txt`](./timing_summary.txt)
332 changes: 332 additions & 0 deletions docs/timing_summary.txt

Large diffs are not rendered by default.

183 changes: 183 additions & 0 deletions docs/utilization_report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
Copyright 1986-2022 Xilinx, Inc. All Rights Reserved. Copyright 2022-2025 Advanced Micro Devices, Inc. All Rights Reserved.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Tool Version : Vivado v.2025.2 (win64) Build 6299465 Fri Nov 14 19:35:11 GMT 2025
| Date : Thu May 28 20:45:19 2026
| Host : Zenbook running 64-bit major release (build 9200)
| Command : report_utilization -hierarchical_min_primitive_count 50 -file C:/Users/harry/code/personal/fpga-stream-processor/fpga-stream-processor/utilization_report.txt -name utilization_2
| Design : top_pipeline
| Device : xc7a35tcpg236-1
| Speed File : -1
| Design State : Synthesized
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Utilization Design Information

Table of Contents
-----------------
1. Slice Logic
1.1 Summary of Registers by Type
2. Memory
3. DSP
4. IO and GT Specific
5. Clocking
6. Specific Feature
7. Primitives
8. Black Boxes
9. Instantiated Netlists

1. Slice Logic
--------------

+-------------------------+------+-------+------------+-----------+-------+
| Site Type | Used | Fixed | Prohibited | Available | Util% |
+-------------------------+------+-------+------------+-----------+-------+
| Slice LUTs* | 25 | 0 | 0 | 20800 | 0.12 |
| LUT as Logic | 25 | 0 | 0 | 20800 | 0.12 |
| LUT as Memory | 0 | 0 | 0 | 9600 | 0.00 |
| Slice Registers | 40 | 0 | 0 | 41600 | 0.10 |
| Register as Flip Flop | 40 | 0 | 0 | 41600 | 0.10 |
| Register as Latch | 0 | 0 | 0 | 41600 | 0.00 |
| F7 Muxes | 0 | 0 | 0 | 16300 | 0.00 |
| F8 Muxes | 0 | 0 | 0 | 8150 | 0.00 |
| Unique Control Sets | 1 | | 0 | 8150 | 0.01 |
+-------------------------+------+-------+------------+-----------+-------+
* Warning! The Final LUT count, after physical optimizations and full implementation, is typically lower. Run opt_design after synthesis, if not already completed, for a more realistic count.
Warning! LUT value is adjusted to account for LUT combining.
Warning! For any ECO changes, please run place_design if there are unplaced instances
** Note: Available Control Sets calculated as Slice * 1, Review the Control Sets Report for more information regarding control sets.


1.1 Summary of Registers by Type
--------------------------------

+-------+--------------+-------------+--------------+
| Total | Clock Enable | Synchronous | Asynchronous |
+-------+--------------+-------------+--------------+
| 0 | _ | - | - |
| 0 | _ | - | Set |
| 0 | _ | - | Reset |
| 0 | _ | Set | - |
| 0 | _ | Reset | - |
| 0 | Yes | - | - |
| 0 | Yes | - | Set |
| 0 | Yes | - | Reset |
| 0 | Yes | Set | - |
| 40 | Yes | Reset | - |
+-------+--------------+-------------+--------------+


2. Memory
---------

+----------------+------+-------+------------+-----------+-------+
| Site Type | Used | Fixed | Prohibited | Available | Util% |
+----------------+------+-------+------------+-----------+-------+
| Block RAM Tile | 0 | 0 | 0 | 50 | 0.00 |
| RAMB36/FIFO* | 0 | 0 | 0 | 50 | 0.00 |
| RAMB18 | 0 | 0 | 0 | 100 | 0.00 |
+----------------+------+-------+------------+-----------+-------+
* Note: Each Block RAM Tile only has one FIFO logic available and therefore can accommodate only one FIFO36E1 or one FIFO18E1. However, if a FIFO18E1 occupies a Block RAM Tile, that tile can still accommodate a RAMB18E1


3. DSP
------

+-----------+------+-------+------------+-----------+-------+
| Site Type | Used | Fixed | Prohibited | Available | Util% |
+-----------+------+-------+------------+-----------+-------+
| DSPs | 0 | 0 | 0 | 90 | 0.00 |
+-----------+------+-------+------------+-----------+-------+


4. IO and GT Specific
---------------------

+-----------------------------+------+-------+------------+-----------+-------+
| Site Type | Used | Fixed | Prohibited | Available | Util% |
+-----------------------------+------+-------+------------+-----------+-------+
| Bonded IOB | 44 | 0 | 0 | 106 | 41.51 |
| Bonded IPADs | 0 | 0 | 0 | 10 | 0.00 |
| Bonded OPADs | 0 | 0 | 0 | 4 | 0.00 |
| PHY_CONTROL | 0 | 0 | 0 | 5 | 0.00 |
| PHASER_REF | 0 | 0 | 0 | 5 | 0.00 |
| OUT_FIFO | 0 | 0 | 0 | 20 | 0.00 |
| IN_FIFO | 0 | 0 | 0 | 20 | 0.00 |
| IDELAYCTRL | 0 | 0 | 0 | 5 | 0.00 |
| IBUFDS | 0 | 0 | 0 | 104 | 0.00 |
| GTPE2_CHANNEL | 0 | 0 | 0 | 2 | 0.00 |
| PHASER_OUT/PHASER_OUT_PHY | 0 | 0 | 0 | 20 | 0.00 |
| PHASER_IN/PHASER_IN_PHY | 0 | 0 | 0 | 20 | 0.00 |
| IDELAYE2/IDELAYE2_FINEDELAY | 0 | 0 | 0 | 250 | 0.00 |
| IBUFDS_GTE2 | 0 | 0 | 0 | 2 | 0.00 |
| ILOGIC | 0 | 0 | 0 | 106 | 0.00 |
| OLOGIC | 0 | 0 | 0 | 106 | 0.00 |
+-----------------------------+------+-------+------------+-----------+-------+


5. Clocking
-----------

+------------+------+-------+------------+-----------+-------+
| Site Type | Used | Fixed | Prohibited | Available | Util% |
+------------+------+-------+------------+-----------+-------+
| BUFGCTRL | 1 | 0 | 0 | 32 | 3.13 |
| BUFIO | 0 | 0 | 0 | 20 | 0.00 |
| MMCME2_ADV | 0 | 0 | 0 | 5 | 0.00 |
| PLLE2_ADV | 0 | 0 | 0 | 5 | 0.00 |
| BUFMRCE | 0 | 0 | 0 | 10 | 0.00 |
| BUFHCE | 0 | 0 | 0 | 72 | 0.00 |
| BUFR | 0 | 0 | 0 | 20 | 0.00 |
+------------+------+-------+------------+-----------+-------+


6. Specific Feature
-------------------

+-------------+------+-------+------------+-----------+-------+
| Site Type | Used | Fixed | Prohibited | Available | Util% |
+-------------+------+-------+------------+-----------+-------+
| BSCANE2 | 0 | 0 | 0 | 4 | 0.00 |
| CAPTUREE2 | 0 | 0 | 0 | 1 | 0.00 |
| DNA_PORT | 0 | 0 | 0 | 1 | 0.00 |
| EFUSE_USR | 0 | 0 | 0 | 1 | 0.00 |
| FRAME_ECCE2 | 0 | 0 | 0 | 1 | 0.00 |
| ICAPE2 | 0 | 0 | 0 | 2 | 0.00 |
| PCIE_2_1 | 0 | 0 | 0 | 1 | 0.00 |
| STARTUPE2 | 0 | 0 | 0 | 1 | 0.00 |
| XADC | 0 | 0 | 0 | 1 | 0.00 |
+-------------+------+-------+------------+-----------+-------+


7. Primitives
-------------

+----------+------+---------------------+
| Ref Name | Used | Functional Category |
+----------+------+---------------------+
| FDRE | 40 | Flop & Latch |
| IBUF | 23 | IO |
| OBUF | 21 | IO |
| LUT2 | 20 | LUT |
| LUT4 | 17 | LUT |
| LUT6 | 5 | LUT |
| LUT3 | 1 | LUT |
| BUFG | 1 | Clock |
+----------+------+---------------------+


8. Black Boxes
--------------

+----------+------+
| Ref Name | Used |
+----------+------+


9. Instantiated Netlists
------------------------

+----------+------+
| Ref Name | Used |
+----------+------+


9 changes: 9 additions & 0 deletions docs/waveforms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Waveforms

This doc contains waveforms from RTL pipeline testing.

## Synchronous Pipeline Test

The waveform shows the synchronous version of the pipeline being tested with fixed input messages.

![Synchronous pipeline waveform](../images/sync_tb_waveform.png)
Binary file added images/sync_tb_waveform.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 29 additions & 19 deletions rtl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,35 @@ This folder contains the Verilog design files for the project.

## Current status

The current setup includes a simple message parser, a filter to check for an invalid type and a pipeline to connect these and decide the output based on the parsed input and filter result.

```text
┌────────────────┐ message type ┌────────────────┐
message │ ├──────────────────►│ │ reject reason
───────────────►│ message_parser │ │ message_filter ├───────────►
│ ├──────────────────►│ │
└────────────────┘ values a&b └────┬────┬──────┘
│ │
│ │
│ │
│ │
│ │
input a&b│ │ valid message?
│ │ ┌───────────────────┐ output a&b
│ └───►│ │
│ │ output_formatter ├───────────►
└────────►│ │
└───────────────────┘
The RTL implements a synchronous message-processing pipeline.

`top_pipeline.v` provides a clocked wrapper, including reset handling, input sampling, registered outputs, and `input_valid` / `output_valid` signalling.

The internal processing modules are all combinational:

- `message_parser.v` splits the 32-bit input message into seperate fields.
- `message_filter.v` checks the parsed fields and produces an accept/reject decision.
- `output_formatter.v` sets the registered output values based on the filter result.

```mermaid
flowchart LR
A("input") --> |"32-bit message"| B["input register"]
A --> |"input_valid"| B

CLK["clk & reset"] -.-> B
CLK -.-> F["output registers"]

B --> C["message_parser"]
C --> |message_type| D["message_filter"]
C --> |value_a & value_b| D
C --> |value_a & value_b| E["output_formatter"]
D --> |accept/reject| E
D --> |reject_reason| F
E --> |formatted values| F

F --> |"value_a & value_b"| G("output")
F --> |"reject_reason"| G
F --> |"output_valid"| G
```

## Message format
Expand Down
2 changes: 1 addition & 1 deletion rtl/message_filter.v
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ module message_filter
else begin
message_valid = 1;
reject_reason = 4'b0000; // passes through filter
end
end
end

endmodule
Loading
Loading