tools/fpga_benchmark.py: parametric Yosys + nextpnr-ecp5 benchmark harness for the LFE5U-45F-8BG381 (speed grade -8, 80 MHz target), sweeping PARALLEL over the neuron layer and parsing Fmax/LUT4/DFF/DSP utilization out of the nextpnr report into JSON/CSV. synth/ecp5/p2, p4, p8: real synthesis+PnR results backing the same-price-tier FPGA comparison (P2: 87.88 MHz PASS, P4: 75.01 MHz FAIL, P8: 147.62 MHz PASS -- non-monotonic, dominated by placement noise since the whole design uses <2% of the device's LUT4 fabric at every setting, and P8 notably maps to 0 DSP blocks vs 8/16 for P2/P4). synth/ecp5/top.v: benchmark harness top-level, reworked to generate deterministic non-constant X/weights/bias via `keep`-attributed generate blocks so Yosys can't constant-fold the datapath away. Also adds .gitignore for Python's __pycache__/*.pyc.
79 lines
1.8 KiB
Verilog
79 lines
1.8 KiB
Verilog
module top (
|
|
input clk,
|
|
input rst,
|
|
input start,
|
|
|
|
output signed [31:0] y_bus,
|
|
output busy,
|
|
output done
|
|
);
|
|
|
|
localparam DATA_WIDTH = 8;
|
|
localparam N_INPUTS = 256;
|
|
localparam N_NEURONS = 4;
|
|
localparam PARALLEL = 2;
|
|
localparam ACC_WIDTH = 32;
|
|
|
|
reg signed [DATA_WIDTH*N_INPUTS-1:0] x_bus;
|
|
reg signed [DATA_WIDTH*N_INPUTS*N_NEURONS-1:0] weights_bus;
|
|
reg signed [DATA_WIDTH*N_NEURONS-1:0] bias_bus;
|
|
|
|
integer i;
|
|
|
|
initial begin
|
|
x_bus = 0;
|
|
weights_bus = 0;
|
|
bias_bus = 0;
|
|
|
|
// X = 1
|
|
for (i = 0; i < N_INPUTS; i = i + 1)
|
|
x_bus[i*DATA_WIDTH +: DATA_WIDTH] = 8'sd1;
|
|
|
|
// Neuron 0: first 32 weights = +1
|
|
for (i = 0; i < 32; i = i + 1)
|
|
weights_bus[
|
|
0*N_INPUTS*DATA_WIDTH +
|
|
i*DATA_WIDTH +:
|
|
DATA_WIDTH
|
|
] = 8'sd1;
|
|
|
|
// Neuron 1: all zero, bias = 10
|
|
bias_bus[1*DATA_WIDTH +: DATA_WIDTH] = 8'sd10;
|
|
|
|
// Neuron 2: all weights = -1
|
|
for (i = 0; i < N_INPUTS; i = i + 1)
|
|
weights_bus[
|
|
2*N_INPUTS*DATA_WIDTH +
|
|
i*DATA_WIDTH +:
|
|
DATA_WIDTH
|
|
] = -8'sd1;
|
|
|
|
// Neuron 3: first 32 weights = +4
|
|
for (i = 0; i < 32; i = i + 1)
|
|
weights_bus[
|
|
3*N_INPUTS*DATA_WIDTH +
|
|
i*DATA_WIDTH +:
|
|
DATA_WIDTH
|
|
] = 8'sd4;
|
|
end
|
|
|
|
layer #(
|
|
.DATA_WIDTH(DATA_WIDTH),
|
|
.N_INPUTS(N_INPUTS),
|
|
.N_NEURONS(N_NEURONS),
|
|
.PARALLEL(PARALLEL),
|
|
.ACC_WIDTH(ACC_WIDTH)
|
|
) u_layer (
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.start(start),
|
|
.x_bus(x_bus),
|
|
.weights_bus(weights_bus),
|
|
.bias_bus(bias_bus),
|
|
.y_bus(y_bus),
|
|
.busy(busy),
|
|
.done(done)
|
|
);
|
|
|
|
endmodule
|