Synthesizable Verilog RTL for a MobileNet-style edge-inference datapath. The design explores a spatial processing-element (PE) array, streamed convolution windows, depthwise mapping, on-chip pooling, semantic scoring, top-k selection, and a small thermal-management path.
DVCon India 2026: submitted design reported as a Top 100 nationwide entry.
The repository is intended to be read as an RTL/architecture project: the quick overview is here, while DESIGN.md records the implementation details, assumptions, and known limitations.
flowchart TD
A[Pixel stream] --> B[Window Generator]
B --> C[Conv2D Mapper]
W[Weight stream] --> Q[Stream Buffer]
Q --> C
C --> D[16 x 16 Systolic Array\n256 PEs by default]
D --> E[Global Average Pool]
E --> F[Semantic Scorer]
F --> G[Top-K Selector]
G --> H[Top-1 output]
T[Thermal Sensor Model] --> U[Thermal Controller]
U --> D
At the top level, MobileNet_Accelerator selects the execution mode from layer_type:
- standard convolution uses the 3x3 window and dense mapper path;
- depthwise convolution maps one channel onto a PE column and uses staggered activations;
- pointwise convolution is represented by the controller's GEMM mode.
The default compute configuration is 16 rows x 16 columns (256 PEs). For depthwise 3x3 mapping, only nine rows carry non-zero activation data; the physical array remains 16 x 16.
| Parameter | Value | Evidence or scope |
|---|---|---|
| RTL | Verilog (.v) |
rtl/ sources and Icarus flow |
| Top module | MobileNet_Accelerator |
rtl/MobileNet_Accelerator.v |
| Default array | 16 x 16 PEs (256 PEs) | Top-level parameters ROWS=16, COLS=16 |
| Activation and weight width | 8-bit signed | PE, Sparsity_MAC, and mapper interfaces |
| Accumulator width | 32-bit signed | Systolic-array and pooling interfaces |
| Convolution window | 3 x 3 | Top-level selects the low 72 bits of the window |
| FPGA target in checked-in reports | Xilinx Kintex UltraScale xcku035-sfva784-1LV-i |
constraints/system.xdc and reports/ |
| Clock constraint | 5.0 ns (200 MHz) | constraints/system.xdc |
| Routed timing result | 207.13 MHz, WNS +0.172 ns | reports/timing_summary.rpt and derived summary |
| Layer modes | Standard, depthwise, pointwise/GEMM | MobileNet_Controller |
| Verification tools | Icarus Verilog; NumPy golden model | scripts/, tb/, and src/golden_model.py |
| License | MIT | LICENSE |
The values below are kept as report-derived estimates, not silicon measurements. The timing result comes from a routed Vivado report. Peak GOPS and layer latency are calculated by scripts/comprehensive_analysis.tcl from 256 MACs/cycle, two operations/MAC, and the reported Fmax. Power uses Vivado's default-toggle-rate analysis; the checked-in power reports mark confidence as low because no activity file is supplied.
| Metric | Reported value | Classification |
|---|---|---|
| Target clock | 200 MHz | Constraint |
| Fmax | 207.13 MHz | Routed timing report / derived from WNS |
| WNS / TNS | +0.172 ns / 0.000 ns | Routed timing report |
| Peak compute | 106.05 GOPS | Derived peak estimate |
| Layer latency | 0.943 ms for 100M operations | Derived estimate |
| Total power at 10% toggle | 0.699 W | Vivado estimate; low confidence |
| Total power at 50% toggle | 0.752 W | Vivado estimate; low confidence |
| Total power at 100% toggle | 0.815 W | Vivado estimate; low confidence |
See reports/final_metrics_summary.txt, reports/timing_summary.rpt, and the three power reports for the source data and assumptions.
Each PE registers activations horizontally and weights/partial sums vertically. Systolic_Array_Core generates the 2-D interconnect, while Systolic_Controller sequences load, compute, drain, and done phases.
Conv2D_Mapper skews the nine 3x3 window values across nine active rows. The current channel is associated with a PE column; a channel-switch pulse can begin loading the next column while the current stream is still being computed. The top-level storage element is a single Stream_Buffer, so this is a lookahead path rather than a verified two-bank ping-pong buffer.
GlobalAvgPool accumulates drained partial sums and emits a packed feature vector. SemanticScorer contains 14 deterministic embedding rows and a registered adder tree. TopKSelector maintains three candidates. At the current top-level integration, task_id and candidate_id are tied to zero; the reusable scorer and selector modules are more general than the exposed top-level classification path.
Hardware-accelerated Top-K selection minimizes the additional latency required for final classification.
Thermal_Sensor is a synthesizable fixed-point compact RC model. Thermal_Controller produces a clock-enable decision from warning/critical thresholds, and the top level feeds that decision into a BUFGCE clock gate. This is a control/modeling feature, not a measurement from a physical temperature sensor.
Install Icarus Verilog, then run the fast self-checking regression used by CI:
bash scripts/run_ci.shThe complete local list, including the longer system-level replay benches, is available with:
bash scripts/run_tests.sh- Icarus Verilog
- Python 3.x
- NumPy
- PyTorch (for the optional software pipeline and benchmark flow)
bash scripts/run_tests.shpython3 src/golden_model.pyGolden-vector generation uses the deterministic NumPy model. The generated files are consumed by the larger integration benches.
Unit testbenches cover the PE, sparse MAC, mapper, pooling, scorer, controller, systolic core, thermal path, top-k selector, and wrapper interfaces.
The fast module regression is the CI gate. The long tb_MobileNet_Accelerator_System.v and tb_MobileNet_Accelerator_Validation.v benches are retained for debug and characterization. A baseline run of the current repository exposed X-propagation in later pooled channels and a consequent top-k mismatch in the system replay; those benches should not be described as end-to-end passing until that datapath issue is fixed.
rtl/ Synthesizable RTL; rtl/thermal/ contains the TMU model
tb/ Self-checking Verilog testbenches
src/ Golden model and software-side experiments
scripts/ Icarus, Vivado, and analysis scripts
constraints/ Vivado XDC constraints
data/golden/ Deterministic input/reference vectors
reports/ Checked-in Vivado timing, power, utilization, and DRC reports
benchmark/ Baseline and optimized software benchmarks
Images/ Repository visualization assets
DESIGN.md Detailed architecture and verification documentation
The checked-in Vivado flow targets the Kintex UltraScale part named in constraints/system.xdc. scripts/comprehensive_analysis.tcl reads the RTL and constraints and emits reports from an already synthesized/implemented Vivado design; it intentionally does not run synthesis or implementation itself. Use Vivado in batch mode or source the script from a project with the expected top module.
Contributions are welcome. Please open an issue before substantial architectural changes. RTL changes should include an appropriate self-checking testbench or regression update, and documentation should distinguish measured results from estimates.
Developed as a submission for the DVCon India 2026 Design Contest.
