Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add files and functionality to simulate an app on the top level. #303

Merged
merged 11 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ synth.txt
synth.v
application_fpga_par.json
application_fpga_par.txt
tb_application_fpga_sim.fst
tb_application_fpga_sim.fst.hier
tb_verilated/
verilated/
*.o
*.asc
*.bin
Expand Down
158 changes: 93 additions & 65 deletions hw/application_fpga/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,23 @@ ICE40_SIM_CELLS = $(shell yosys-config --datdir/ice40/cells_sim.v)


# FPGA specific source files.
FPGA_SRC = \
FPGA_VERILOG_SRCS = \
$(P)/rtl/application_fpga.v \
$(P)/core/clk_reset_gen/rtl/clk_reset_gen.v
$(P)/core/clk_reset_gen/rtl/clk_reset_gen.v \
$(P)/core/trng/rtl/trng.v

# Testbench simulation specific source files.
SIM_VERILOG_SRCS = \
$(P)/tb/tb_application_fpga_sim.v \
$(P)/tb/application_fpga_sim.v \
$(P)/tb/reset_gen_sim.v \
$(P)/tb/trng_sim.v

# Verilator simulation specific source files.
VERILATOR_FPGA_SRC = \
VERILATOR_VERILOG_SRCS = \
$(P)/tb/application_fpga_sim.v \
$(P)/tb/reset_gen_sim.v
$(P)/tb/reset_gen_sim.v \
$(P)/tb/trng_sim.v

# Common verilog source files.
VERILOG_SRCS = \
Expand All @@ -97,8 +106,7 @@ VERILOG_SRCS = \
$(P)/core/tk1/rtl/udi_rom.v \
$(P)/core/uart/rtl/uart_core.v \
$(P)/core/uart/rtl/uart_fifo.v \
$(P)/core/uart/rtl/uart.v \
$(P)/core/trng/rtl/trng.v
$(P)/core/uart/rtl/uart.v

# PicoRV32 verilog source file
PICORV32_SRCS = \
Expand Down Expand Up @@ -176,6 +184,10 @@ $(TESTFW_OBJS): $(FIRMWARE_DEPS)
firmware.elf: $(FIRMWARE_OBJS) $(P)/fw/tk1/firmware.lds
$(CC) $(CFLAGS) $(FIRMWARE_OBJS) $(LDFLAGS) -o $@

simfirmware.elf: CFLAGS += -DSIMULATION
simfirmware.elf: $(FIRMWARE_OBJS) $(P)/fw/tk1/firmware.lds
$(CC) $(CFLAGS) $(FIRMWARE_OBJS) $(LDFLAGS) -o $@

qemu_firmware.elf: CFLAGS += -DQEMU_CONSOLE
qemu_firmware.elf: firmware.elf
mv firmware.elf qemu_firmware.elf
Expand Down Expand Up @@ -216,6 +228,8 @@ bram_fw.hex:

firmware.hex: firmware.bin firmware_size_mismatch
python3 $(P)/tools/makehex/makehex.py $< $(BRAM_FW_SIZE) > $@
simfirmware.hex: simfirmware.bin simfirmware_size_mismatch
python3 $(P)/tools/makehex/makehex.py $< $(BRAM_FW_SIZE) > $@
testfw.hex: testfw.bin testfw_size_mismatch
python3 $(P)/tools/makehex/makehex.py $< $(BRAM_FW_SIZE) > $@

Expand Down Expand Up @@ -249,7 +263,11 @@ LINT_FLAGS = \
--timescale 1ns/1ns \
-DNO_ICE40_DEFAULT_ASSIGNMENTS

lint: $(FPGA_SRC) $(VERILOG_SRCS) $(PICORV32_SRCS) $(ICE40_SIM_CELLS)
lint: $(FPGA_VERILOG_SRCS) \
$(SIM_VERILOG_SRCS) \
$(VERILOG_SRCS) \
$(PICORV32_SRCS) \
$(ICE40_SIM_CELLS)
$(LINT) $(LINT_FLAGS) \
-DBRAM_FW_SIZE=$(BRAM_FW_SIZE) \
-DFIRMWARE_HEX=\"$(P)/firmware.hex\" \
Expand Down Expand Up @@ -278,21 +296,21 @@ CHECK_FORMAT_FLAGS = \
--inplace \
--verify

fmt: $(FPGA_SRC) $(VERILATOR_FPGA_SRC) $(VERILOG_SRCS)
fmt: $(FPGA_VERILOG_SRCS) $(SIM_VERILOG_SRCS) $(VERILATOR_VERILOG_SRCS) $(VERILOG_SRCS)
$(FORMAT) $(FORMAT_FLAGS) $^
.PHONY: fmt

# Temporary fix using grep, since the verible with --verify flag only returns
# error if the last file is malformatted.
checkfmt: $(FPGA_SRC) $(VERILATOR_FPGA_SRC) $(VERILOG_SRCS)
checkfmt: $(FPGA_VERILOG_SRCS) $(SIM_VERILOG_SRCS) $(VERILATOR_VERILOG_SRCS) $(VERILOG_SRCS)
$(FORMAT) $(CHECK_FORMAT_FLAGS) $^ 2>&1 | \
grep "Needs formatting" && exit 1 || true
.PHONY: checkfmt

#-------------------------------------------------------------------
# Build Verilator compiled simulation for the design.
#-------------------------------------------------------------------
verilator: $(VERILATOR_FPGA_SRC) $(VERILOG_SRCS) $(PICORV32_SRCS) \
verilator: $(VERILATOR_VERILOG_SRCS) $(VERILOG_SRCS) $(PICORV32_SRCS) \
firmware.hex $(ICE40_SIM_CELLS) \
$(P)/tb/application_fpga_verilator.cc
verilator \
Expand All @@ -301,17 +319,18 @@ verilator: $(VERILATOR_FPGA_SRC) $(VERILOG_SRCS) $(PICORV32_SRCS) \
-Wall \
-Wno-COMBDLY \
-Wno-lint \
-Wno-UNOPTFLAT \
-DBRAM_FW_SIZE=$(BRAM_FW_SIZE) \
-DFIRMWARE_HEX=\"$(P)/firmware.hex\" \
-DUDS_HEX=\"$(P)/data/uds.hex\" \
-DUDI_HEX=\"$(P)/data/udi.hex\" \
--cc \
--exe \
--Mdir verilated \
--top-module application_fpga \
--top-module application_fpga_sim \
$(filter %.v, $^) \
$(filter %.cc, $^)
make -C verilated -f Vapplication_fpga.mk
make -C verilated -f Vapplication_fpga_sim.mk
.PHONY: verilator

#-------------------------------------------------------------------
Expand All @@ -334,7 +353,7 @@ tb:

YOSYS_FLAG ?=

synth.json: $(FPGA_SRC) $(VERILOG_SRCS) $(PICORV32_SRCS) bram_fw.hex \
synth.json: $(FPGA_VERILOG_SRCS) $(VERILOG_SRCS) $(PICORV32_SRCS) bram_fw.hex \
$(P)/data/uds.hex $(P)/data/udi.hex
$(YOSYS_PATH)yosys \
-v3 \
Expand Down Expand Up @@ -381,41 +400,43 @@ application_fpga_testfw.bin: application_fpga.asc bram_fw.hex testfw.hex
@-$(RM) $<.tmp

#-------------------------------------------------------------------
# post-synthesis functional simulation.
# Build testbench simulation for the design
#-------------------------------------------------------------------
synth_tb.vvp: $(P)/tb/tb_application_fpga.v synth.json
iverilog \
-o $@ \
-s tb_application_fpga synth.v $(P)/tb/tb_application_fpga.v \
tb_application_fpga: $(SIM_VERILOG_SRCS) \
$(VERILOG_SRCS) \
$(PICORV32_SRCS) \
$(ICE40_SIM_CELLS) \
simfirmware.hex
python3 ./tools/app_bin_to_spram_hex.py \
./tb/app.bin \
./tb/output_spram0.hex \
./tb/output_spram1.hex \
./tb/output_spram2.hex \
./tb/output_spram3.hex \
|| { echo -e "\n -- Put your app.bin to simulate in the \"tb\" directory\n"; false; }
verilator \
-j $(shell nproc --ignore=1) \
--binary \
--cc \
--exe \
--Mdir tb_verilated \
--trace-fst \
--trace-structs \
--top-module tb_application_fpga_sim \
--timescale 1ns/1ns \
--timing \
-Wno-WIDTHEXPAND \
-Wno-UNOPTFLAT \
-DNO_ICE40_DEFAULT_ASSIGNMENTS \
$(ICE40_SIM_CELLS)
chmod -x $@

synth_sim: synth_tb.vvp
vvp -N $<
.PHONY: synth_sim

synth_sim_vcd: synth_tb.vvp
vvp -N $< +vcd
.PHONY: synth_sim_vcd

#-------------------------------------------------------------------
# post-place and route functional simulation.
#-------------------------------------------------------------------
route.v: application_fpga.asc $(P)/data/$(PIN_FILE)
icebox_vlog -L -n application_fpga -sp $(P)/data/$(PIN_FILE) $< > $@

route_tb.vvp: route.v tb/tb_application_fpga.v
iverilog -o $@ -s tb_application_fpga $^ $(ICE40_SIM_CELLS)
chmod -x $@

route_sim: route_tb.vvp
vvp -N $<
.PHONY: route_sim

route_sim_vcd: route_tb.vvp
vvp -N $< +vcd
.PHONY: route_sim_vcd
-DAPP_SIZE=$(shell ls -l tb/app.bin| awk '{print $$5}') \
-DBRAM_FW_SIZE=$(BRAM_FW_SIZE) \
-DFIRMWARE_HEX=\"$(P)/simfirmware.hex\" \
-DUDS_HEX=\"$(P)/data/uds.hex\" \
-DUDI_HEX=\"$(P)/data/udi.hex\" \
$(filter %.v, $^)
make -C tb_verilated -f Vtb_application_fpga_sim.mk
./tb_verilated/Vtb_application_fpga_sim \
&& { echo -e "\n -- Wave simulation saved to tb_application_fpga_sim.fst\n"; true; }

#-------------------------------------------------------------------
# FPGA device programming.
Expand Down Expand Up @@ -449,14 +470,11 @@ view: tb_application_fpga_vcd
#-------------------------------------------------------------------
# Cleanup.
#-------------------------------------------------------------------
clean: clean_fw clean_tb
clean: clean_sim clean_fw clean_tb
rm -f bram_fw.hex
rm -f synth.{v,json,txt} route.v application_fpga.{asc,bin,vcd} application_fpga_testfw.bin
rm -f tb_application_fpga.vvp synth_tb.vvp route_tb.vvp
rm -f synth.{v,json,txt} application_fpga.{asc,bin} application_fpga_testfw.bin
rm -f application_fpga_par.{json,txt}
rm -f *.vcd
rm -f lint_issues.txt
rm -rf verilated
rm -f tools/tpt/*.hex
rm -rf tools/tpt/__pycache__
.PHONY: clean
Expand All @@ -469,6 +487,15 @@ clean_fw:
rm -f qemu_firmware.elf
.PHONY: clean_fw

clean_sim:
rm -f simfirmware.{elf,elf.map,bin,hex}
rm -f tb_application_fpga_sim.fst
rm -f tb_application_fpga_sim.fst.hier
rm -f tb/output_spram*.hex
rm -rf tb_verilated
rm -rf verilated
.PHONY: clean_sim

clean_tb:
make -C core/timer/toolruns clean
make -C core/tk1/toolruns clean
Expand All @@ -487,20 +514,21 @@ help:
@echo ""
@echo "Supported targets:"
@echo "------------------"
@echo "all Build all targets."
@echo "check Run static analysis on firmware."
@echo "splint Run splint static analysis on firmware."
@echo "firmware.elf Build firmware ELF file."
@echo "firmware.hex Build firmware converted to hex, to be included in bitstream."
@echo "bram_fw.hex Build a fake BRAM file that will be filled in later after place-n-route."
@echo "verilator Build Verilator simulation program"
@echo "lint Run lint on Verilog source files."
@echo "tb Run all testbenches"
@echo "prog_flash Program device flash with FGPA bitstream including firmware (using the RPi Pico-based programmer)."
@echo "prog_flash_testfw Program device flash as above, but with testfw."
@echo "clean Delete all generated files."
@echo "clean_fw Delete only generated files for firmware. Useful for fw devs."
@echo "clean_tb Delete only generated files for testbenches."
@echo "all Build all targets."
@echo "check Run static analysis on firmware."
@echo "splint Run splint static analysis on firmware."
@echo "firmware.elf Build firmware ELF file."
@echo "firmware.hex Build firmware converted to hex, to be included in bitstream."
@echo "bram_fw.hex Build a fake BRAM file that will be filled in later after place-n-route."
@echo "verilator Build Verilator simulation program"
@echo "tb_application_fpga Build testbench simulation for the design"
@echo "lint Run lint on Verilog source files."
@echo "tb Run all testbenches"
@echo "prog_flash Program device flash with FGPA bitstream including firmware (using the RPi Pico-based programmer)."
@echo "prog_flash_testfw Program device flash as above, but with testfw."
@echo "clean Delete all generated files."
@echo "clean_fw Delete only generated files for firmware. Useful for fw devs."
@echo "clean_tb Delete only generated files for testbenches."

#=======================================================================
# EOF Makefile
Expand Down
2 changes: 1 addition & 1 deletion hw/application_fpga/application_fpga.bin.sha256
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2a3928e8587c8d5d7eca6048c6448dc1d16d52a9a25d3ca5026bec3e7fb14ef3 application_fpga.bin
44086edb70377991b57d3f1c231f743fcf0c2c9d2303843ec133f76cc42449a8 application_fpga.bin
6 changes: 4 additions & 2 deletions hw/application_fpga/core/tk1/rtl/tk1.v
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@

`default_nettype none

module tk1 (
module tk1 #(
parameter [31:0] APP_SIZE = 32'h0
) (
input wire clk,
input wire reset_n,

Expand Down Expand Up @@ -255,7 +257,7 @@ module tk1 (
gpio3_reg <= 1'h0;
gpio4_reg <= 1'h0;
app_start_reg <= 32'h0;
app_size_reg <= 32'h0;
app_size_reg <= APP_SIZE;
blake2s_addr_reg <= 32'h0;
cdi_mem[0] <= 32'h0;
cdi_mem[1] <= 32'h0;
Expand Down
12 changes: 12 additions & 0 deletions hw/application_fpga/fw/tk1/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ static enum state loading_commands(const struct frame_header *hdr,
const uint8_t *cmd, enum state state,
struct context *ctx);
static void run(const struct context *ctx);
#if !defined(SIMULATION)
static uint32_t xorwow(uint32_t state, uint32_t acc);
#endif
static void scramble_ram(void);

static void print_hw_version(void)
Expand Down Expand Up @@ -364,6 +366,7 @@ static void run(const struct context *ctx)
__builtin_unreachable();
}

#if !defined(SIMULATION)
static uint32_t xorwow(uint32_t state, uint32_t acc)
{
state ^= state << 13;
Expand All @@ -372,9 +375,13 @@ static uint32_t xorwow(uint32_t state, uint32_t acc)
state += acc;
return state;
}
#endif

static void scramble_ram(void)
{
// Can't fill RAM if we are simulating, data has already been loaded
// into RAM.
#if !defined(SIMULATION)
uint32_t *ram = (uint32_t *)(TK1_RAM_BASE);

// Fill RAM with random data
Expand All @@ -386,6 +393,7 @@ static void scramble_ram(void)
data_state = xorwow(data_state, data_acc);
ram[w] = data_state;
}
#endif

// Set RAM address and data scrambling parameters
*ram_addr_rand = rnd_word();
Expand Down Expand Up @@ -414,6 +422,10 @@ int main(void)

scramble_ram();

#if defined(SIMULATION)
run(&ctx);
#endif

for (;;) {
switch (state) {
case FW_STATE_INITIAL:
Expand Down
Loading