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

Rework Build System #7

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
65640e7
uart: Rework Makefile
Forty-Bot Aug 10, 2018
8576d6d
Rename port files
Forty-Bot Aug 11, 2018
b71339d
Create a top-level makefile
Forty-Bot Aug 11, 2018
86dabb9
Change default device to 8k
Forty-Bot Aug 11, 2018
069082a
blank: Use top-level makefile
Forty-Bot Aug 11, 2018
e919c07
blinky: Use top-level makefile
Forty-Bot Aug 11, 2018
ce2b234
buttons_bounce: Use top-level makefile
Forty-Bot Aug 11, 2018
fc0e52b
buttons_debounce: Use top-level makefile
Forty-Bot Aug 11, 2018
c41cda4
buttons_nopullup: Use top-level makefile
Forty-Bot Aug 11, 2018
c4f0820
fsm_simple: Use top-level makefile
Forty-Bot Aug 11, 2018
8b410d5
Remove unneeded .gitignores
Forty-Bot Aug 11, 2018
8848a68
Allow makefiles to be run in the same directory
Forty-Bot Aug 11, 2018
d0be3e1
Update readme to reflect build system changes
Forty-Bot Aug 11, 2018
bb7606e
Fix targets not being rebuilt on makefile change
Forty-Bot Jan 27, 2019
fee5d85
Add VERBOSE option
Forty-Bot Jan 27, 2019
236452b
Move duplicated makefile code into common.mk
Forty-Bot Jan 27, 2019
dfb55fa
Use ln over cp for requiring files in build
Forty-Bot Jan 27, 2019
985e4fa
Add common.mk
Forty-Bot Jan 27, 2019
a9c7e2c
Update Readme
Forty-Bot Jan 27, 2019
d82bbcd
Add additional options for synthesis
Forty-Bot Mar 19, 2019
515a5a6
Fix subdir builds not working
Forty-Bot Mar 19, 2019
28de818
Remove some projects
Forty-Bot Mar 21, 2019
c59fedd
Make a few commands quieter
Forty-Bot Mar 21, 2019
d1cd38e
Switch to board-specific pcfs
Forty-Bot Mar 21, 2019
97bf807
Load previous variables on start
Forty-Bot Mar 21, 2019
e1616f6
Remove unused pcf files
Forty-Bot Mar 21, 2019
40d91d4
Remove unused variable M_SRC
Forty-Bot Mar 21, 2019
8e327a3
Add option to customize flash program
Forty-Bot Mar 21, 2019
2914342
Add passthrough project
Forty-Bot Mar 21, 2019
9f15b1c
Add BUTS variable for buttons
Forty-Bot Mar 22, 2019
94119f6
Modify passthrough to use BUTS
Forty-Bot Mar 22, 2019
f01ee0f
Finish removing references to per-project pcfs
Forty-Bot Mar 24, 2019
c5a21a9
Split defined into their own variable; set default nettype none globally
Forty-Bot Mar 24, 2019
ca90396
Add verilator support (broken)
Forty-Bot Mar 24, 2019
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@

# matlab storage files
*.mat

build
133 changes: 133 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Use := where you can, as it only gets evaluated once
BUILD := build

# Load previous values of variables
VARS := $(foreach VAR,$(wildcard $(BUILD)/*.var),$(basename $(notdir $(VARIABLE))))
$(foreach VAR,$(VARS),$(eval $(VAR) ?= $(shell cat $(BUILD)/$(VAR).var)))

BOARD ?= Lattice/ICE40HX1K-STICK-EVN
include boards/$(BOARD)/cfg
FAMILY := $(strip $(subst lp,,$(subst hx,, $(subst up,,$(DEVICE)))))
# List of variables set by the board cfg
# We don't just use VARS since this could be the first run,
# so some of these variables may not have a .var file
BOARD_VARS := DEVICE PACKAGE LEDS BUTS CLOCK
BOARD_DEFINES := $(foreach VAR,$(BOARD_VARS),$(and $($(VAR)),-D$(VAR)=$($(VAR))))

ifdef VERBOSE
Q :=
else
Q :=1
endif

PNR ?= arachne-pnr
SYNTH ?= yosys
FLASH ?= iceprog

# Necessary so VPATH doesn't get reinterpreted
VPATH :=
MODULES := uart blank blinky passthrough

# SRC holds all source files
SRC :=

.PHONY: all clean burn-% time-% test-% cov-% FORCE

all:

$(BUILD):
mkdir -p $@

# First pattern rule creates a .blif from a .v
# We also have an order-only prerequisite on the build dir
# This means it must be created first, but make doesn't care if it's out-of-date
# The timestamp of a directory changes whenever a file within it is created
# So if we didn't ignore it, we would build everything three times
# Quick introduction to make variables:
# $@ current target, what goes to the left of a make rule
# $< First dependency
# $^ all non-order-only dependencies
# $* the stem of an implicit rule -- what % matches in %.blif
$(BUILD)/%.blif: %.v | $(BUILD)
$(SYNTH) $(and $(Q),-q) -p "read_verilog -noautowire $(BOARD_DEFINES) $^; synth_ice40 -top $* -blif $@"

# .PHONY causes targets to be rebuilt every make, and built even if there is an up-to-date file
# Depending on a .PHONY target will cause the rule to be run every time
# but make will pay attention to timestamps and not run further dependencies if the target doesn't get updated
FORCE:

# We are going to exploit that here to make sure we rebuild if the user changes the value of DEVICE
# We compare the current value of the variable to what is in env
# If they are different, we update the file
# If they are the same we don't
# Anything which depends on $(BUILD)/DEVICE.var will only update if DEVICE changes
$(BUILD)/%.var: FORCE | $(BUILD)
@echo "$($*)" | cmp -s - "$@" || echo "$($*)" > $@

# Keep .var file around even though they are intermediate targets
.PRECIOUS: $(BUILD)/%.var

$(BUILD)/%: %
ln -f $< $@

# Note that yosys does not run if you only change DEVICE, just things from here down
%.asc: %.blif boards/$(BOARD)/pcf $(BUILD)/FAMILY.var $(BUILD)/PACKAGE.var $(BUILD)/BOARD.var $(BUILD)/PNR.var
$(PNR) $(and $(Q),-q) -d $(FAMILY) -P $(PACKAGE) -p boards/$(BOARD)/pcf -o $@ $<

%.bin: %.asc
icepack $< $@

burn-%: $(BUILD)/%.bin $(BUILD)/FLASH.var
$(FLASH) $<

time-%: $(BUILD)/%.asc boards/$(BOARD)/pcf $(BUILD)/DEVICE.var $(BUILD)/PACKAGE.var $(BUILD)/BOARD.var
icetime -t -d $(DEVICE) -P $(PACKAGE) -p boards/$(BOARD)/pcf $<

clean:
rm -rf $(BUILD)

include $(addsuffix /Makefile,$(MODULES))

# The following snippet Copyright 2003-2019 by Wilson Snyder, 2019 Sean Anderson
# This program is free software; you can redistribute it and/or modify
# it under the terms of either the GNU Lesser General Public License Version 3
# or the Perl Artistic License Version 2.0.

VERILATOR ?= verilator
VERILATOR_COVERAGE ?= verilator_coverage
# Generate C++ in executable form
VERILATOR_FLAGS += -cc --exe
# Optimize
VERILATOR_FLAGS += -O2 -x-assign 0
# Warn abount lint issues; may not want this on less solid designs
VERILATOR_FLAGS += -Wall
# Make waveforms
VERILATOR_FLAGS += --trace
# Check SystemVerilog assertions
VERILATOR_FLAGS += --assert
# Generate coverage analysis
VERILATOR_FLAGS += --coverage
# end snippet

# Similar to BOARD_DEFINES, but we need to be careful to remove non-c-friendly characters
# signed numbers are NOT supported
sanitize = $(lastword $(subst 'h,' 0x,$(subst 'd,' ,$(subst _,,$1))))
export USER_CPPFLAGS := $(foreach VAR,$(BOARD_VARS),$(and $($(VAR)),-D$(VAR)=$(call sanitize,$($(VAR)))))

$(BUILD)/test-%:
mkdir -p $@

test-%: | $(BUILD)/test-%
$(VERILATOR) $(VERILATOR_FLAGS) $$(echo "$(BOARD_DEFINES)") -Mdir $(BUILD)/test-$* --prefix $* $^
$(MAKE) -C $(BUILD)/test-$* -f $*.mk
$(BUILD)/test-$*/$* +trace

cov-%: test-%
$(VERILATOR_COVERAGE) --annotate $(BUILD)/test-$*/logs/annotated $(BUILD)/test-$*/logs/coverage.dat

# Because our sources/pinmaps depend on the makefile
# all targets will get rebuilt every time the makefile changes
# Additionally, we need to depend on BOARD
# (and SYNTH/VERILATOR* since this is the only place to put it)
$(SRC): Makefile $(BUILD)/BOARD.var $(BUILD)/SYNTH.var $(BUILD)/VERILATOR.var $(BUILD)/VERILATOR_COVERAGE.var
@touch $@
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,15 @@ https://www.dropbox.com/s/3qgiq0j6qj3910f/keypad_instructions.pdf?dl=0

## Downloading, compiling, and programming the example projects
In order to download this repository, type `git clone https://github.com/nesl/ice40_examples.git ice40_examples` on the command line. Within the repository you will find a GPL license file, this readme, and several different example project folders such as "blinky." Within a given project folder, you will see:
* top.v -- the highest level Verilog file, including all pin inputs (e.g. clocks and button lines) and outputs (e.g. LEDs)
* (other modules.v) -- any other required modules (e.g. UART transmitters) referenced in top.v
* pinmap.pcf -- the pin map file relating variable names referenced in top.v to physical I/O pins on the ICE40 HX8K. The syntax here is `set_io <wire_name> <physical pin name>`. You can add the `--warn-no-port` option if you'd like the compiler to warn you if a specified pin does not exist on a given device.
* Makefile -- this is a typical Unix Makefile that dictates the synthesis and programming flow. For the example projects, this file provides two commands of interest: `make` and `make burn`. `make` will compile your verilog project into a binary bitstream, and `make burn` will download this bitstream onto your FPGA device through USB.
* build/ -- this is a folder where all intermediate build files are stored -- e.g. netlists, ascii bitstream, binary bistream.
* `<folder_name>.v` -- the highest level Verilog file, including all pin inputs (e.g. clocks and button lines) and outputs (e.g. LEDs)
* (`other_modules.v`) -- any other required modules (e.g. UART transmitters) referenced in `<folder_name>.v`
* `<folder_name>_<footprint>.pcf` -- the pin map file relating variable names referenced in `<folder_name>.v` to physical I/O pins on the ICE40 HX8K. The syntax here is `set_io <wire_name> <physical pin name>`. You can add the `--warn-no-port` option if you'd like the compiler to warn you if a specified pin does not exist on a given device.
* `Makefile` -- this is a sub-makefile which is included by the top-level makefile, but can also be used on its own. For the example projects, this file provides two commands of interest: `make` and `make burn`. `make` will compile your verilog project into a binary bitstream, and `make burn` will download this bitstream onto your FPGA device through USB.

In order to compile an example project, navigate to that directory on your terminal. Type `make` to compile the project. When this finishes, type `make burn` to load the compiled binary onto your FPGA, provided it's connected over USB.

You can also type `make` in the top directory to compile all projects. To load a project onto your FPGA, use `make burn-<project>`.

Note for OSX: If you are having difficulties programming a project onto the FPGA with `make burn`, see the section below on UART transmission under the UART project.

## Example Projects List
Expand Down Expand Up @@ -160,12 +161,12 @@ If on a Windows machine (for viewing purposes only--i.e. this does not apply if

## Project Design Process:
In order to create your own project, start by copying the template provided in the blank project folder. The general design process looks like this:
1. Write your top-level Verilog code in top.v. Any additional Verilog files required can be placed at the same level as top.v (in the project folder).
1. Write your top-level Verilog code in `<module>.v`. Any additional Verilog files required can be placed at the same level as `<module>.v` (in the project folder).

2. Modify your Makefile: change `PROJ` to be your project name, and if any additional Verilog files are required, they should follow the `FILES = top.v` line, using the format `FILES += newfile.v` where `newfile.v` is the name of any additional Verilog file you have written. You can use this syntax for however many files you need.
2. Modify your Makefile: update the `MODULE` variable (this doesn't need to match the folder name, but does need to be unique across all modules). If any additional Verilog files are required, they should be added to `M_VSRC`. Remember to separate each file with spaces. Any other source files (including pcf files) should be added to `M_SRC`.

3. Modify pinmap.pcf. If any pins are required other than the input clock and LEDs, add a line to the pinmap.pcf file using the format `set_io --warn-no-port <wire_name> <physical pin name>`.
3. Modify `<project>_<footprint>.pcf`. `<footprint>` should be the package for your chip which is passed do `arachne-pnr`. The iCE40-HX8K-CT256 uses `ct256`, and the iCE40-HX1K-TQ144 uses `tq144`. For a full list of supported packages, see [the icestorm documentation](http://www.clifford.at/icestorm/#flags). If any pins are required other than the input clock and LEDs, add a line to the file using the format `set_io --warn-no-port <wire_name> <physical pin name>`.

4. Compile your project by running `make` from the project directory
4. Compile your project by running `make` from either the project or top-level directory.

5. If your project successfully compiles, connect your FPGA over USB and type `make burn` to program the binary to your FPGA.
5. If your project successfully compiles, connect your FPGA over USB and type `make burn` from the project directory, or `make burn-<module>` from the top-level directory to program the binary to your FPGA.
1 change: 0 additions & 1 deletion blank/.gitignore

This file was deleted.

28 changes: 3 additions & 25 deletions blank/Makefile
Original file line number Diff line number Diff line change
@@ -1,26 +1,4 @@
# Project setup
PROJ = blank
BUILD = ./build
DEVICE = 8k
FOOTPRINT = ct256
MODULE := blank
M_VSRC := blank.v

# Files
FILES = top.v

.PHONY: all clean burn

all:
# if build folder doesn't exist, create it
mkdir -p $(BUILD)
# synthesize using Yosys
yosys -p "synth_ice40 -top top -blif $(BUILD)/$(PROJ).blif" $(FILES)
# Place and route using arachne
arachne-pnr -d $(DEVICE) -P $(FOOTPRINT) -o $(BUILD)/$(PROJ).asc -p pinmap.pcf $(BUILD)/$(PROJ).blif
# Convert to bitstream using IcePack
icepack $(BUILD)/$(PROJ).asc $(BUILD)/$(PROJ).bin

burn:
iceprog $(BUILD)/$(PROJ).bin

clean:
rm build/*
include $(realpath $(dir $(lastword $(MAKEFILE_LIST))))/../common.mk
8 changes: 8 additions & 0 deletions blank/blank.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Blink an LED provided an input clock
/* module */
module blank (hwclk, led);
/* I/O */
input hwclk;
output [`LEDS - 1:0] led;

endmodule
10 changes: 0 additions & 10 deletions blank/pinmap.pcf

This file was deleted.

15 changes: 0 additions & 15 deletions blank/top.v

This file was deleted.

1 change: 0 additions & 1 deletion blinky/.gitignore

This file was deleted.

28 changes: 3 additions & 25 deletions blinky/Makefile
Original file line number Diff line number Diff line change
@@ -1,26 +1,4 @@
# Project setup
PROJ = blinky
BUILD = ./build
DEVICE = 8k
FOOTPRINT = ct256
MODULE := blinky
M_VSRC := blinky.v

# Files
FILES = top.v

.PHONY: all clean burn

all:
# if build folder doesn't exist, create it
mkdir -p $(BUILD)
# synthesize using Yosys
yosys -p "synth_ice40 -top top -blif $(BUILD)/$(PROJ).blif" $(FILES)
# Place and route using arachne
arachne-pnr -d $(DEVICE) -P $(FOOTPRINT) -o $(BUILD)/$(PROJ).asc -p pinmap.pcf $(BUILD)/$(PROJ).blif
# Convert to bitstream using IcePack
icepack $(BUILD)/$(PROJ).asc $(BUILD)/$(PROJ).bin

burn:
iceprog $(BUILD)/$(PROJ).bin

clean:
rm build/*
include $(realpath $(dir $(lastword $(MAKEFILE_LIST))))/../common.mk
23 changes: 23 additions & 0 deletions blinky/blinky.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Blink an LED provided an input clock

/* module */
module blinky (hwclk, led);
input hwclk;
output reg [`LEDS - 1:0] led;

/*
* led[`LEDS-1] should blink at 1hz
* the *switching* speed should be 2 hz
*/
parameter cycles = `CLOCK / (2 * `LEDS);
reg [32:0] counter = 32'b0;

always @ (posedge hwclk) begin
if (counter == cycles) begin
led <= led + 1;
counter <= 32'b0;
end else
counter <= counter + 1;
end

endmodule
10 changes: 0 additions & 10 deletions blinky/pinmap.pcf

This file was deleted.

33 changes: 0 additions & 33 deletions blinky/top.v

This file was deleted.

5 changes: 5 additions & 0 deletions boards/Lattice/ICE40HX1K-STICK-EVN/cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
DEVICE := hx1k
PACKAGE := tq144
LEDS := 5
BUTS :=
CLOCK := 32'd12_000_000
Loading