Members: Saleem Bekkali - bekkali@usc.edu Maia Piechocki - piechock@usc.edu Conner Ngueyn - connerng@usc.edu
A small 64→8→10 MLP for digit classification. Inputs are 8-bit signed. Weights are int8, biases int32, accumulators int32. Per-vector max-abs scaling is applied before each linear layer; ReLU between layers; argmax for class. Python (MLP.py) trains on sklearn digits and generates matching int artifacts for RTL.
- mlp.v: RTL for linear_layer_64x8, relu, linear_layer_8x10, max_finder, mlp_top. Includes runtime copies from generated constants, signed scaling, and signed division fixes.
- mlp_tb.v: Testbench with 8 canned cases (zeros; half +10/-10; alternating ±20; ramp -32..31; all 127; all -128; vertical line; horizontal line). Prints logits/preds; optional debug prints for scaling.
- mlp_params_int.vh: Auto-generated int8 weights/int32 biases for both layers (no include guards; include inside modules).
- python_expected_int.txt: Auto-generated expected logits/probs/preds for the 8 canned cases.
- MLP.py: Python train/quantize/export script (int8 weights, per-vector scaling to mirror RTL) and int pipeline reference.
- screenshots: show the waveforms and demonstrate how to get the training weights and biases along with the expected outputs.
When the done signal goes high, the expected output (Python output) is supposed to align with the predicted output (DUT output).
- In repo root, the Python environment needs to match the original MLP.py provided to students.
- Run:
python MLP.py - Copy the regenerated
mlp_params_int.vhandpython_expected_int.txtinto your simulation folder (e.g.,C:/intelFPGA_lite/18.1/ee454/final_project).
From the simulation folder containing the four files above:
vdel -lib work -all
vlib work
vlog mlp.v mlp_tb.v
vsim work.mlp_tb
run -all
add wave -radix decimal sim:/mlp_tb/start sim:/mlp_tb/done sim:/mlp_tb/predicted_class
add wave -radix decimal sim:/mlp_tb/uut/state
add wave -radix decimal sim:/mlp_tb/layer1_unpacked* sim:/mlp_tb/relu_unpacked* sim:/mlp_tb/layer2_unpacked*
run 400ns # view Test 1
- Test 1 (all zeros): matches line 1 of python_expected_int.txt; predicted class per exp_pred[1].
- Test 2 (half +10/-10): layer1 debug shows scaled[0]=127, scaled[32]=-127; logits
[-4445, -13979, -10915, 3838, -7362, 5771, -14884, -4536, -1351, 14370]; predicted class 9.
- Scaling uses signed division; packed/unpacked slices are explicitly signed to preserve negatives.
- Include
mlp_params_int.vhinside each linear layer (already done in mlp.v); no include guards. - Keep the simulation folder in sync with freshly generated artifacts after rerunning MLP.py.
See inline comments and MLP.py for reference behavior and artifact generation.