File size: 4,926 Bytes
0ba037b | 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 | # FPGA build for the bit-string accelerator.
#
# make sim UART-level testbench on the RTL (Icarus + Verilator)
# make lint verilator -Wall on both board tops
# make icebreaker bitstream for iCEBreaker (iCE40UP5K) -> build/icebreaker.bin
# make ulx3s bitstream for ULX3S (ECP5 25F) -> build/ulx3s.bit
# make gl-sim testbench on post-synthesis netlists (iCE40, ECP5)
# make cosim host tool (host/) against the RTL through a pseudo-terminal
# make prog-icebreaker / prog-ulx3s program a connected board
# make all lint, sim, cosim, gl-sim and both bitstreams
#
# Tools: yosys, nextpnr-ice40, nextpnr-ecp5, icepack (icestorm), ecppack
# (prjtrellis), iverilog, verilator; iceprog / openFPGALoader to program.
YOSYS ?= yosys
IVERILOG ?= iverilog
VVP ?= vvp
VERILATOR ?= verilator
BUILD ?= build
SEED ?= 1
ULX3S_DEVICE ?= 25k # 12k, 25k, 45k or 85k to match the board
YOSYS_DAT ?= /usr/share/yosys # Yosys data dir with ice40/ and ecp5/ cell models
CORE := ../rtl/bit_accelerator.sv rtl/uart_rx.sv rtl/uart_tx.sv rtl/word_memory.sv rtl/fpga_top.sv
TB := tb/tb_fpga_top.sv
.PHONY: all sim sim-icarus sim-verilator lint icebreaker ulx3s gl-sim gl-sim-ice40 gl-sim-ecp5 \
cosim host prog-icebreaker prog-ulx3s clean
.DEFAULT_GOAL := all
all: lint sim cosim gl-sim icebreaker ulx3s
$(BUILD):
mkdir -p $@
# ------------------------------------------------------------------ RTL checks
sim: sim-icarus sim-verilator
sim-icarus: | $(BUILD)
$(IVERILOG) -g2012 -o $(BUILD)/tb_fpga.vvp $(CORE) $(TB)
$(VVP) -n $(BUILD)/tb_fpga.vvp
sim-verilator: | $(BUILD)
$(VERILATOR) --binary --timing --timescale 1ns/1ps -Wno-fatal -Wno-lint --top-module tb_fpga_top \
-Mdir $(BUILD)/verilator $(CORE) $(TB) >/dev/null
$(BUILD)/verilator/Vtb_fpga_top
lint:
$(VERILATOR) --lint-only -Wall $(CORE) rtl/power_on_reset.sv boards/icebreaker_top.sv --top-module icebreaker_top
$(VERILATOR) --lint-only -Wall $(CORE) rtl/power_on_reset.sv boards/ulx3s_top.sv --top-module ulx3s_top
# ------------------------------------------------------------------ host tool
host:
cd host && cargo fmt --check && cargo clippy --all-targets -- -D warnings && cargo test
cosim: host
BUILD=$(BUILD) sim/cosim.sh 2000 1
# ------------------------------------------------------------------ iCEBreaker
icebreaker: $(BUILD)/icebreaker.bin
$(BUILD)/icebreaker.json: $(CORE) rtl/power_on_reset.sv boards/icebreaker_top.sv | $(BUILD)
$(YOSYS) -q -l $(BUILD)/icebreaker_synth.log -p "read_verilog -sv $^; synth_ice40 -top icebreaker_top -json $@"
$(BUILD)/icebreaker.asc: $(BUILD)/icebreaker.json boards/icebreaker.pcf
nextpnr-ice40 --up5k --package sg48 --json $< --pcf boards/icebreaker.pcf --asc $@ \
--freq 12 --seed $(SEED) -l $(BUILD)/icebreaker_pnr.log -q
$(BUILD)/icebreaker.bin: $(BUILD)/icebreaker.asc
icepack $< $@
@grep -E "Max frequency|ICESTORM_LC:|ICESTORM_RAM:" $(BUILD)/icebreaker_pnr.log | tail -3
prog-icebreaker: $(BUILD)/icebreaker.bin
iceprog $<
# ------------------------------------------------------------------ ULX3S
ulx3s: $(BUILD)/ulx3s.bit
$(BUILD)/ulx3s.json: $(CORE) rtl/power_on_reset.sv boards/ulx3s_top.sv | $(BUILD)
$(YOSYS) -q -l $(BUILD)/ulx3s_synth.log -p "read_verilog -sv $^; synth_ecp5 -top ulx3s_top -json $@"
$(BUILD)/ulx3s.config: $(BUILD)/ulx3s.json boards/ulx3s.lpf
nextpnr-ecp5 --$(strip $(ULX3S_DEVICE)) --package CABGA381 --json $< --lpf boards/ulx3s.lpf \
--textcfg $@ --seed $(SEED) -l $(BUILD)/ulx3s_pnr.log -q
$(BUILD)/ulx3s.bit: $(BUILD)/ulx3s.config
ecppack --compress $< $@
@grep -E "Max frequency|TRELLIS_COMB:|DP16KD:" $(BUILD)/ulx3s_pnr.log | tail -3
prog-ulx3s: $(BUILD)/ulx3s.bit
openFPGALoader --board ulx3s $<
# ------------------------------------------------------------------ gate level
# The netlists are built with CLKS_PER_BIT = 8 so the UART testbench runs fast.
gl-sim: gl-sim-ice40 gl-sim-ecp5
gl-sim-ice40: | $(BUILD)
$(YOSYS) -q -p "read_verilog -sv $(CORE); chparam -set CLKS_PER_BIT 8 fpga_top; \
synth_ice40 -top fpga_top; write_verilog -noattr $(BUILD)/fpga_top_ice40_gl.v"
$(IVERILOG) -g2012 -DGATE_LEVEL -o $(BUILD)/gl_ice40.vvp \
$(BUILD)/fpga_top_ice40_gl.v $(strip $(YOSYS_DAT))/ice40/cells_sim.v $(TB)
$(VVP) -n $(BUILD)/gl_ice40.vvp
# Yosys ships DP16KD (ECP5 block RAM) only as a black box, so this netlist
# keeps the memory in LUT RAM (-nobram); everything else is the real mapping.
gl-sim-ecp5: | $(BUILD)
$(YOSYS) -q -p "read_verilog -sv $(CORE); chparam -set CLKS_PER_BIT 8 fpga_top; \
synth_ecp5 -nobram -top fpga_top; write_verilog -noattr $(BUILD)/fpga_top_ecp5_gl.v"
$(IVERILOG) -g2012 -DGATE_LEVEL -I$(strip $(YOSYS_DAT))/ecp5 -o $(BUILD)/gl_ecp5.vvp \
$(BUILD)/fpga_top_ecp5_gl.v $(strip $(YOSYS_DAT))/ecp5/cells_sim.v $(TB)
$(VVP) -n $(BUILD)/gl_ecp5.vvp
clean:
rm -rf $(BUILD)
cd host && cargo clean
|