Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
167 lines (133 loc) · 8.16 KB
/
Copy pathMakefile
File metadata and controls
167 lines (133 loc) · 8.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# tiny-gpu on the Tang Nano 20K
# Common tasks. The FPGA build/flash steps shell out to the helper scripts,
# which set up the macOS library paths the Gowin CLI tools need.
IVERILOG ?= iverilog
VVP ?= vvp
VERILATOR ?= verilator
.PHONY: mlc sim-mlp2 run-mlp2 drill drill-peek sim sim-vl sim-loadrun sim-divergence sim-divmerge sim-warps sim-mac32 sim-mlp build build-oss build-oss-max flash flash-oss flash-oss-max flash-persist bench asm demo record clean run-jpp sim-nn sim-mnist-jpp sim-jpp-features sim-mnist-jpp-full run-mnist-jpp
# Run any testbench under Verilator (the tool the job posting names) instead of
# iverilog. Verilator is a stricter linter and much faster; --timing lets it
# handle the #-delay testbenches. Usage: make sim-vl TB=test/tb_mac32.sv
TB ?= test/tb_mac32.sv
VL_WARN = -Wno-fatal -Wno-WIDTH -Wno-UNOPTFLAT -Wno-CASEINCOMPLETE -Wno-BLKANDNBLK -Wno-PINMISSING
sim-vl: ## Run a testbench under Verilator. Usage: make sim-vl TB=test/tb_mac32.sv
$(VERILATOR) --binary --timing $(VL_WARN) -j 0 --top-module tb --Mdir obj_vl $(TB) src/*.sv -o sim_vl
./obj_vl/sim_vl
# Verilog interview drills: type the module in drills/NN_name.sv, the
# testbench grades you. See drills/README.md.
D ?= 01_counter
drill: ## Run a drill against its checker. Usage: make drill D=01_counter
$(IVERILOG) -g2012 -s tb -o drills/sim_$(D) drills/$(D).sv drills/tb/tb_$(D).sv
$(VVP) drills/sim_$(D)
drill-peek: ## Run the reference solution for a drill (verify the checker, or peek)
$(IVERILOG) -g2012 -s tb -o drills/sim_$(D) drills/solutions/$(D).sv drills/tb/tb_$(D).sv
$(VVP) drills/sim_$(D)
# J++: compile a .jpp source -> asm -> hex, then stream it to the FPGA and read
# the reply. Usage: make run-jpp JPP=software/program.jpp READ=8
JPP ?= software/program.jpp
READ ?= 8
run-jpp: ## Compile + run a J++ program on the FPGA. Usage: make run-jpp JPP=software/foo.jpp
cd software && cargo run --quiet --bin jpp -- $(notdir $(JPP)) program.asm
cd software && cargo run --quiet -- program.asm program.hex
cd software && python3 send_kernel.py program.hex --read $(READ)
sim: ## Build + run the simulation (self-checks that 5*3 = 15)
$(IVERILOG) -g2012 -s tb -o gpu_sim test/tb.sv src/*.sv
$(VVP) gpu_sim
sim-loadrun: ## General load->run->readback: stream a kernel+data over UART, run, check reply
cd software && cargo run --quiet -- sum_kernel.asm sum_kernel.hex
$(IVERILOG) -g2012 -s tb -o sim_loadrun test/tb_loadrun.sv src/*.sv
$(VVP) sim_loadrun
sim-divergence: ## Validate per-lane SIMT branch divergence (lanes take different paths)
cd software && cargo run --quiet -- divergence_kernel.asm divergence_kernel.hex
$(IVERILOG) -g2012 -s tb -o sim_divergence test/tb_divergence.sv src/*.sv
$(VVP) sim_divergence
sim-divmerge: ## Validate divergence + reconvergence (common code runs on all lanes after merge)
cd software && cargo run --quiet -- divmerge_kernel.asm divmerge_kernel.hex
$(IVERILOG) -g2012 -s tb -o sim_divmerge test/tb_divmerge.sv src/*.sv
$(VVP) sim_divmerge
sim-mnist-jpp-full: ## The whole MNIST CNN in J++ (mnist.jpp), board config 1 warp x 9 threads: maps + prediction vs reference
cd software && cargo run --quiet --bin jpp -- mnist.jpp mnist_jpp.asm
cd software && cargo run --quiet -- mnist_jpp.asm mnist_jpp.hex
cd software && python3 run_mnist_jpp.py --sim 0
$(IVERILOG) -g2012 -s tb -o sim_mnist_jpp_full test/tb_mnist_jpp_full.sv src/*.sv
$(VVP) sim_mnist_jpp_full
run-mnist-jpp: ## Classify 50 test images on the FPGA with the J++ MNIST model (needs oss_build/tiny_gpu_ml.fs loaded)
cd software && cargo run --quiet --bin jpp -- mnist.jpp mnist_jpp.asm
cd software && cargo run --quiet -- mnist_jpp.asm mnist_jpp.hex
cd software && python3 run_mnist_jpp.py 50
sim-jpp-features: ## J++ if / max / big constants on hardware, with threads taking different branches
cd software && cargo test --quiet --test jpp_features
cd software && cargo run --quiet --bin jpp -- jpp_features.jpp jpp_features.asm
cd software && cargo run --quiet -- jpp_features.asm jpp_features.hex
$(IVERILOG) -g2012 -s tb -o sim_jpp_features test/tb_jpp_features.sv src/*.sv
$(VVP) sim_jpp_features
sim-warps: ## Prove 2 warps run distinct global thread IDs (BLOCK_DIM=8 -> 8 lanes 0..7)
cd software && cargo run --quiet -- tid_demo.asm tid_demo.hex
$(IVERILOG) -g2012 -s tb -o sim_warps test/tb_warps.sv src/*.sv
$(VVP) sim_warps
sim-mac32: ## Prove the full 32-bit MAC result reads back via MAC Rd,#n (4 bytes -> 4800)
cd software && cargo run --quiet -- mac_read32.asm mac_read32.hex
$(IVERILOG) -g2012 -s tb -o sim_mac32 test/tb_mac32.sv src/*.sv
$(VVP) sim_mac32
sim-mlp: ## Parallel FC layer: 9 lanes each compute+write their own neuron (per-lane write path)
cd software && cargo run --quiet -- mlp_parallel.asm mlp_parallel.hex
$(IVERILOG) -g2012 -s tb -o sim_mlp test/tb_mlp.sv src/*.sv
$(VVP) sim_mlp
sim-mnist-jpp: ## AI demo: the MNIST classifier written in J++ (mnist_fc.jpp) predicts digit 7
cd software && cargo run --quiet --bin jpp -- mnist_fc.jpp mnist_fc_jpp.asm
cd software && cargo run --quiet -- mnist_fc_jpp.asm mnist_fc_jpp.hex
$(IVERILOG) -g2012 -s tb -o sim_mnist_jpp test/tb_mnist_jpp.sv src/*.sv
$(VVP) sim_mnist_jpp
# ---- ML compiler: model JSON -> data image + kernel, nothing baked in the bitstream ----
MODEL ?= mlp_169_32_10
IMAGE ?= 0
TORCH_PY ?= $(HOME)/cnn_chip/venv/bin/python
# per-model frontend; default is the torch-free random-weight exporter
EXPORT_mnist_mlp = $(TORCH_PY) export_torch.py --image $(IMAGE)
EXPORT_mnist_cnn = $(EXPORT_mnist_mlp)
mlc: ## Compile a model: export -> graph_compiler -> asm -> hex. Usage: make mlc MODEL=mnist_mlp IMAGE=3
cd software && $(or $(EXPORT_$(MODEL)),python3 export_model.py) models/$(MODEL).json
cd software && cargo run --quiet --bin graph_compiler -- models/$(MODEL).json
cd software && cargo run --quiet -- build/$(MODEL).asm build/$(MODEL).hex
sim-mlp2: ## AI demo: 2-layer int8 MLP, compiled end to end, checked byte-for-byte vs the reference
$(MAKE) mlc
$(IVERILOG) -g2012 -s tb -o sim_mlp2 test/tb_mlp2.sv src/*.sv
$(VVP) sim_mlp2
FUZZ_N ?= 200
fuzz: ## Differential fuzz: FUZZ_N random models, graph reference == compiler reference == RTL (seed with FUZZ_SEED)
cd software && python3 fuzz_mlc.py --n $(FUZZ_N) --seed $(or $(FUZZ_SEED),1)
run-mlp2: ## Run the compiled 2-layer MLP on the FPGA and read back scores + prediction
$(MAKE) mlc
cd software && python3 send_kernel.py build/$(MODEL).hex \
--data-hex build/$(MODEL).data.hex --pad 1 --read 24
sim-nn: ## AI demo: a neuron written in J++ (nn.jpp) runs on the MAC, computes 64
cd software && cargo run --quiet --bin jpp -- nn.jpp nn.asm
cd software && cargo run --quiet -- nn.asm nn.hex
$(IVERILOG) -g2012 -s tb -o sim_nn test/tb_nn.sv src/*.sv
$(VVP) sim_nn
bench: ## Measure real ALU ops/s on the board (needs the max18 bitstream flashed)
cd software && cargo run --quiet -- bench_ops.asm bench_ops.hex
python3 software/bench_host.py
demo: ## Serve the draw-a-digit web demo at http://localhost:8000
python3 demo/server.py
record: ## Capture FPGA runs into demo/recordings/ for the Gallery (use --offline for no board)
python3 demo/record.py
asm: ## Re-assemble software/test_kernel.asm -> software/kernel.hex
cd software && cargo run --quiet
build: ## Synthesize + place & route -> impl/pnr/tiny_gpu.fs
./build_fpga.sh
build-oss: ## Open-source bitstream (yosys+nextpnr+apicula). GowinSynthesis crashes on this design; set OSS_CAD_SUITE first
bash oss_build/run_oss.sh
flash-oss: ## Flash the open-source-built bitstream into SRAM
openFPGALoader -b tangnano20k oss_build/tiny_gpu_oss.fs
build-oss-max: ## MAX AI-capable bitstream: 2 cores x 1 warp x 9 lanes = 18 ALU lanes, per-lane writes (78% LUT, 140 MHz). Set OSS_CAD_SUITE first
bash oss_build/build_cfg.sh 1 9 9 tiny_gpu_max18
flash-oss-max: ## Flash the 18-lane MAX bitstream into SRAM
openFPGALoader -b tangnano20k oss_build/tiny_gpu_max18.fs
flash: ## Load the bitstream into SRAM (volatile, gone on power cycle)
./flash.sh
flash-persist: ## Write the bitstream to external SPI flash (survives reboot)
./flash.sh flash
clean:
rm -f gpu_sim *.vcd
rm -rf impl