verilog-blink: add verilog version of blink example
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
af89bcc7f3
commit
9b0463108f
6 changed files with 451 additions and 0 deletions
92
verilog-blink/Makefile
Normal file
92
verilog-blink/Makefile
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
PACKAGE ?= blink
|
||||
TOP ?= $(PACKAGE)
|
||||
|
||||
# Currently GIT_VERSION is unusd and there are no tags, so skip calculating it
|
||||
#GIT_VERSION := $(shell git describe --tags)
|
||||
|
||||
# Default programs
|
||||
NEXTPNR ?= nextpnr-ice40
|
||||
YOSYS ?= yosys
|
||||
ICEPACK ?= icepack
|
||||
|
||||
PCF_PATH ?= pcf
|
||||
|
||||
# Add Windows and Unix support
|
||||
RM = rm -rf
|
||||
COPY = cp -a
|
||||
PATH_SEP = /
|
||||
ifeq ($(OS),Windows_NT)
|
||||
COPY = copy
|
||||
RM = del
|
||||
PATH_SEP = \\
|
||||
endif
|
||||
|
||||
ifeq ($(FOMU_REV),evt3)
|
||||
PCF ?= $(PCF_PATH)/fomu-evt3.pcf
|
||||
PKG ?= sg48
|
||||
YOSYSFLAGS?= -D EVT=1 -D EVT3=1 -D HAVE_PMOD=1
|
||||
PNRFLAGS ?= --up5k --package $(PKG)
|
||||
else ifeq ($(FOMU_REV),evt2)
|
||||
PCF ?= $(PCF_PATH)/fomu-evt2.pcf
|
||||
PKG ?= sg48
|
||||
YOSYSFLAGS?= -D EVT=1 -D EVT2=1 -D HAVE_PMOD=1
|
||||
PNRFLAGS ?= --up5k --package $(PKG)
|
||||
else ifeq ($(FOMU_REV),evt1)
|
||||
PCF ?= $(PCF_PATH)/fomu-evt2.pcf
|
||||
PKG ?= sg48
|
||||
YOSYSFLAGS?= -D EVT=1 -D EVT1=1 -D HAVE_PMOD=1
|
||||
PNRFLAGS ?= --up5k --package $(PKG)
|
||||
else ifeq ($(FOMU_REV),hacker)
|
||||
PCF ?= $(PCF_PATH)/fomu-hacker.pcf
|
||||
PKG ?= uwg30
|
||||
YOSYSFLAGS?= -D HACKER=1
|
||||
PNRFLAGS ?= --up5k --package $(PKG)
|
||||
else ifeq ($(FOMU_REV),pvt1)
|
||||
PCF ?= $(PCF_PATH)/fomu-pvt1.pcf
|
||||
PKG ?= uwg30
|
||||
YOSYSFLAGS?= -D PVT=1 -D PVT1=1
|
||||
PNRFLAGS ?= --up5k --package $(PKG)
|
||||
else
|
||||
$(error Unrecognized FOMU_REV value. must be "evt1", "evt2", "evt3", "pvt1", or "hacker")
|
||||
endif
|
||||
|
||||
BUILD_DIR = build
|
||||
VSOURCES = $(wildcard *.v)
|
||||
QUIET = @
|
||||
|
||||
ALL = all
|
||||
TARGET = $(PACKAGE).bin
|
||||
CLEAN = clean
|
||||
|
||||
$(ALL): $(TARGET)
|
||||
$(QUIET) echo "Built '$(PACKAGE)' for Fomu $(FOMU_REV)"
|
||||
|
||||
run: $(TARGET)
|
||||
fomu-flash -f $(TARGET)
|
||||
|
||||
$(BUILD_DIR)/$(PACKAGE).json: $(VSOURCES) | $(BUILD_DIR)
|
||||
$(QUIET) echo " SYNTH $@"
|
||||
$(QUIET) $(YOSYS) $(YOSYSFLAGS) -p 'synth_ice40 -top $(TOP) -json $@' $(PACKAGE).v
|
||||
|
||||
$(BUILD_DIR)/$(PACKAGE).asc: $(BUILD_DIR)/$(PACKAGE).json $(PCF)
|
||||
$(QUIET) echo " PNR $@"
|
||||
$(QUIET) $(NEXTPNR) $(PNRFLAGS) --json $(BUILD_DIR)/$(PACKAGE).json --pcf $(PCF) --asc $@
|
||||
|
||||
$(TARGET): $(BUILD_DIR)/$(PACKAGE).asc
|
||||
$(QUIET) echo " PACK $@"
|
||||
$(QUIET) $(ICEPACK) $(BUILD_DIR)/$(PACKAGE).asc $@
|
||||
|
||||
$(BUILD_DIR):
|
||||
$(QUIET) mkdir $(BUILD_DIR)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
$(QUIET) echo " RM $(subst /,$(PATH_SEP),$(wildcard $(BUILD_DIR)/*.json))"
|
||||
-$(QUIET) $(RM) $(subst /,$(PATH_SEP),$(wildcard $(BUILD_DIR)/*.json))
|
||||
$(QUIET) echo " RM $(subst /,$(PATH_SEP),$(wildcard $(BUILD_DIR)/*.asc))"
|
||||
-$(QUIET) $(RM) $(subst /,$(PATH_SEP),$(wildcard $(BUILD_DIR)/*.asc))
|
||||
$(QUIET) echo " RM $(TARGET) $(PACKAGE).bin"
|
||||
-$(QUIET) $(RM) $(subst /,$(PATH_SEP),abc.history)
|
||||
$(QUIET) echo " RM $(TARGET) abc.history"
|
||||
-$(QUIET) $(RM) $(TARGET) $(PACKAGE).bin
|
||||
237
verilog-blink/blink.v
Normal file
237
verilog-blink/blink.v
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
// Simple tri-colour LED blink example, with button control
|
||||
//
|
||||
// Green LED blinks forever. Blue LED turned on when Button 5 is pressed.
|
||||
// Red LED turned on when Button 6 is pressed.
|
||||
//
|
||||
// LOG2DELAY controls the division of the module clock to the bit interval
|
||||
// (by requiring count to 2 ** LOG2DELAY before changing LED state bits)
|
||||
//
|
||||
// On EVT Fomu boards:
|
||||
//
|
||||
// 1st LED colour - Blue - controlled by pressing Button 5, or connect 1 to 2
|
||||
// 2nd LED colour - Red - controlled by pressing Button 6, or connect 3 to 4
|
||||
// 3rd LED colour - Green - controlled by clock (blinking)
|
||||
//
|
||||
// On DVT / Hacker / Production Fomu boards:
|
||||
//
|
||||
// 1st LED colour - Blue - turn on by connecting pin 1 to pin 2
|
||||
// 2nd LED colour - Green - controlled by clock (blinking)
|
||||
// 3rd LED colour - Red - turn on by connecting pin 3 to pin 4
|
||||
//
|
||||
// We use `defines to handle these two cases, because the SB_RGBA_DRV
|
||||
// iCE40UP5K hard macro is unable to do RGBn to output pin mapping internally
|
||||
// (the RGB0 / RGB1 / RGB2 parameters to SB_RGBA_DRV *must* be mapped
|
||||
// to the same named RGB0 / RGB1 / RGB2 physical pins; arachne-pnr
|
||||
// errors if they are not, and currently nextpnr just ignores mismapped
|
||||
// pins and enforces this mapping)
|
||||
//
|
||||
// This is all kludged into a single file to make a standalone simple test;
|
||||
// a better design would wrap SB_RGBA_DRV into a Fomu specific module and
|
||||
// hide the LED colour mapping; and also set the appropriate pins for
|
||||
// the buttons at instantiation time.
|
||||
//
|
||||
`ifdef EVT
|
||||
`define BLUEPWM RGB0PWM
|
||||
`define REDPWM RGB1PWM
|
||||
`define GREENPWM RGB2PWM
|
||||
`else
|
||||
`ifdef PVT
|
||||
`define GREENPWM RGB0PWM
|
||||
`define REDPWM RGB1PWM
|
||||
`define BLUEPWM RGB2PWM
|
||||
`else
|
||||
`define BLUEPWM RGB0PWM
|
||||
`define GREENPWM RGB1PWM
|
||||
`define REDPWM RGB2PWM
|
||||
`endif
|
||||
`endif
|
||||
|
||||
module blink (
|
||||
output rgb0, // SB_RGBA_DRV external pins
|
||||
output rgb1,
|
||||
output rgb2,
|
||||
output usb_dp,
|
||||
output usb_dn,
|
||||
output usb_dn,
|
||||
output usb_dp_pu,
|
||||
`ifdef HAVE_PMOD
|
||||
output pmod_1, // PMOD ouput connector (on EVT boards)
|
||||
output pmod_2,
|
||||
output pmod_3,
|
||||
output pmod_4,
|
||||
`endif
|
||||
input user_1, // User touchable pins
|
||||
output user_2, // Connect 1-2 to enable blue LED
|
||||
output user_3, // Connect 3-4 to enable red LED
|
||||
input user_4,
|
||||
`ifdef EVT
|
||||
input user_5, // Button 5 on EVT only
|
||||
input user_6, // Button 6 on EVT only
|
||||
`endif
|
||||
input clki // Clock
|
||||
);
|
||||
|
||||
assign usb_dp = 1'b0;
|
||||
assign usb_dn = 1'b0;
|
||||
assign usb_dp_pu = 1'b0;
|
||||
|
||||
// Connect to system clock (with buffering)
|
||||
wire clkosc;
|
||||
SB_GB clk_gb (
|
||||
.USER_SIGNAL_TO_GLOBAL_BUFFER(clki),
|
||||
.GLOBAL_BUFFER_OUTPUT(clkosc)
|
||||
);
|
||||
|
||||
assign clk = clkosc;
|
||||
|
||||
// Configure user pins so that we can detect the user connecting
|
||||
// 1-2 or 3-4 with conductive material.
|
||||
//
|
||||
// We do this by grounding user_2 and user_3, and configuring inputs
|
||||
// with pullups on user_1 and user_4.
|
||||
//
|
||||
localparam SB_IO_TYPE_SIMPLE_INPUT = 6'b000001;
|
||||
|
||||
wire user_1_pulled;
|
||||
SB_IO #(
|
||||
.PIN_TYPE(SB_IO_TYPE_SIMPLE_INPUT),
|
||||
.PULLUP(1'b1)
|
||||
) user_1_io (
|
||||
.PACKAGE_PIN(user_1),
|
||||
.OUTPUT_ENABLE(1'b0),
|
||||
.INPUT_CLK(clk),
|
||||
.D_IN_0(user_1_pulled),
|
||||
);
|
||||
|
||||
assign user_2 = 1'b0;
|
||||
assign user_3 = 1'b0;
|
||||
|
||||
wire user_4_pulled;
|
||||
SB_IO #(
|
||||
.PIN_TYPE(SB_IO_TYPE_SIMPLE_INPUT),
|
||||
.PULLUP(1'b 1)
|
||||
) user_4_io (
|
||||
.PACKAGE_PIN(user_4),
|
||||
.OUTPUT_ENABLE(1'b0),
|
||||
.INPUT_CLK(clk),
|
||||
.D_IN_0(user_4_pulled),
|
||||
);
|
||||
|
||||
// On EVT boards, there are also physical buttons
|
||||
//
|
||||
`ifdef EVT
|
||||
// Connect first physical button, with pullup enabled
|
||||
wire user_5_pulled;
|
||||
SB_IO #(
|
||||
.PIN_TYPE(SB_IO_TYPE_SIMPLE_INPUT),
|
||||
.PULLUP(1'b 1)
|
||||
) user_5_io (
|
||||
.PACKAGE_PIN(user_5),
|
||||
.OUTPUT_ENABLE(1'b0),
|
||||
.INPUT_CLK(clk),
|
||||
.D_IN_0(user_5_pulled),
|
||||
);
|
||||
|
||||
// Connect second physical button, with pullup enabled
|
||||
wire user_6_pulled;
|
||||
SB_IO #(
|
||||
.PIN_TYPE(SB_IO_TYPE_SIMPLE_INPUT),
|
||||
.PULLUP(1'b 1)
|
||||
) user_6_io (
|
||||
.PACKAGE_PIN(user_6),
|
||||
.OUTPUT_ENABLE(1'b0),
|
||||
.INPUT_CLK(clk),
|
||||
.D_IN_0(user_6_pulled),
|
||||
);
|
||||
|
||||
// Allow touch buttons or physical buttons to control LEDs
|
||||
wire enable_blue = ~user_1_pulled | ~user_5_pulled;
|
||||
wire enable_red = ~user_4_pulled | ~user_6_pulled;
|
||||
`else
|
||||
// On non-EVT platorms, there are only touch buttons
|
||||
wire enable_blue = ~user_1_pulled;
|
||||
wire enable_red = ~user_4_pulled;
|
||||
`endif
|
||||
|
||||
// Use system PLL module to divide system clock
|
||||
// (connected to pmod output below)
|
||||
wire pll_out;
|
||||
SB_PLL40_CORE #(
|
||||
.FEEDBACK_PATH("SIMPLE"),
|
||||
.DIVR(4'b0010), // DIVR = 2
|
||||
.DIVF(7'b0110001), // DIVF = 49
|
||||
.DIVQ(3'b010), // DIVQ = 2
|
||||
.FILTER_RANGE(3'b001) // FILTER_RANGE = 1
|
||||
) mypll (
|
||||
.RESETB(1'b1),
|
||||
.BYPASS(1'b0),
|
||||
.REFERENCECLK(clk),
|
||||
.PLLOUTCORE(pll_out),
|
||||
);
|
||||
|
||||
// Use counter logic to divide system clock
|
||||
// (for blinking LED state)
|
||||
//
|
||||
// BITS controls LED state
|
||||
// LOG2DELAY controls divisor
|
||||
// -- requires counting to 2**LOG2DELAY before spilling onto LED state BITS
|
||||
//
|
||||
localparam BITS = 5;
|
||||
localparam LOG2DELAY = 21;
|
||||
|
||||
reg [28:0] counter = 0;
|
||||
reg [BITS-1:0] outcnt;
|
||||
|
||||
always @(posedge clk) begin
|
||||
counter <= counter + 1;
|
||||
outcnt <= counter >> LOG2DELAY;
|
||||
end
|
||||
|
||||
// Make signals available on PMOD header output for scope
|
||||
// (or to inspect during simulation)
|
||||
`ifdef HAVE_PMOD
|
||||
assign pmod_1 = clk;
|
||||
assign pmod_2 = outcnt ^ (outcnt >> 1);
|
||||
assign pmod_3 = counter[0];
|
||||
assign pmod_4 = pll_out;
|
||||
`endif
|
||||
|
||||
// Instantiate iCE40 LED driver hard logic, connecting up
|
||||
// latched button state, counter state, and LEDs.
|
||||
//
|
||||
SB_RGBA_DRV RGBA_DRIVER (
|
||||
.CURREN(1'b1),
|
||||
.RGBLEDEN(1'b1),
|
||||
.`BLUEPWM(enable_blue), // Blue
|
||||
.`REDPWM(enable_red), // Red
|
||||
.`GREENPWM(counter[23]), // Green (blinking)
|
||||
.RGB0(rgb0),
|
||||
.RGB1(rgb1),
|
||||
.RGB2(rgb2)
|
||||
);
|
||||
|
||||
// Parameters from iCE40 UltraPlus LED Driver Usage Guide, pages 19-20
|
||||
//
|
||||
// https://www.latticesemi.com/-/media/LatticeSemi/Documents/ApplicationNotes/IK/ICE40LEDDriverUsageGuide.ashx?document_id=50668
|
||||
//
|
||||
localparam RGBA_CURRENT_MODE_FULL = "0b0";
|
||||
localparam RGBA_CURRENT_MODE_HALF = "0b1";
|
||||
|
||||
// Current levels in Full / Half mode
|
||||
localparam RGBA_CURRENT_04MA_02MA = "0b000001";
|
||||
localparam RGBA_CURRENT_08MA_04MA = "0b000011";
|
||||
localparam RGBA_CURRENT_12MA_06MA = "0b000111";
|
||||
localparam RGBA_CURRENT_16MA_08MA = "0b001111";
|
||||
localparam RGBA_CURRENT_20MA_10MA = "0b011111";
|
||||
localparam RGBA_CURRENT_24MA_12MA = "0b111111";
|
||||
|
||||
// Set parameters of RGBA_DRIVER (output current)
|
||||
//
|
||||
// Mapping of RGBn to LED colours determined experimentally
|
||||
//
|
||||
defparam RGBA_DRIVER.CURRENT_MODE = RGBA_CURRENT_MODE_HALF;
|
||||
defparam RGBA_DRIVER.RGB0_CURRENT = RGBA_CURRENT_08MA_04MA; // Blue
|
||||
defparam RGBA_DRIVER.RGB1_CURRENT = RGBA_CURRENT_08MA_04MA; // Red
|
||||
defparam RGBA_DRIVER.RGB2_CURRENT = RGBA_CURRENT_08MA_04MA; // Green
|
||||
|
||||
endmodule
|
||||
37
verilog-blink/pcf/fomu-evt2.pcf
Normal file
37
verilog-blink/pcf/fomu-evt2.pcf
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
set_io rgb0 39
|
||||
set_io rgb1 40
|
||||
set_io rgb2 41
|
||||
set_io pmoda_1 25
|
||||
set_io pmoda_2 26
|
||||
set_io pmoda_3 27
|
||||
set_io pmoda_4 28
|
||||
set_io pmod_1 25
|
||||
set_io pmod_2 26
|
||||
set_io pmod_3 27
|
||||
set_io pmod_4 28
|
||||
set_io clki_alt 20
|
||||
set_io clki 44
|
||||
set_io user_1 48
|
||||
set_io user_2 47
|
||||
set_io user_3 46
|
||||
set_io user_4 45
|
||||
set_io user_5 42
|
||||
set_io user_6 38
|
||||
set_io spi_mosi 14
|
||||
set_io spi_miso 17
|
||||
set_io spi_clk 15
|
||||
set_io spi_io2 18
|
||||
set_io spi_io3 19
|
||||
set_io spi_cs 16
|
||||
set_io uart_tx 21
|
||||
set_io uart_rx 13
|
||||
set_io usb_dn 37
|
||||
set_io usb_dp 34
|
||||
set_io usb_dp_pu 35
|
||||
set_io usb_dn_pu 36
|
||||
set_io dbg_1 20
|
||||
set_io dbg_2 12
|
||||
set_io dbg_3 11
|
||||
set_io dbg_4 23
|
||||
set_io dbg_5 10
|
||||
set_io dbg_6 9
|
||||
41
verilog-blink/pcf/fomu-evt3.pcf
Normal file
41
verilog-blink/pcf/fomu-evt3.pcf
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
set_io rgb0 39
|
||||
set_io rgb1 40
|
||||
set_io rgb2 41
|
||||
set_io pmod_1 28
|
||||
set_io pmod_2 27
|
||||
set_io pmod_3 26
|
||||
set_io pmod_4 23
|
||||
set_io pmoda_1 28
|
||||
set_io pmoda_2 27
|
||||
set_io pmoda_3 26
|
||||
set_io pmoda_4 23
|
||||
set_io clki_alt 20
|
||||
set_io clki 44
|
||||
set_io user_1 48
|
||||
set_io user_2 47
|
||||
set_io user_3 46
|
||||
set_io user_4 45
|
||||
set_io user_5 42
|
||||
set_io user_6 38
|
||||
set_io pmodb_1 48
|
||||
set_io pmodb_2 47
|
||||
set_io pmodb_3 46
|
||||
set_io pmodb_4 45
|
||||
set_io spi_mosi 14
|
||||
set_io spi_miso 17
|
||||
set_io spi_clk 15
|
||||
set_io spi_io2 18
|
||||
set_io spi_io3 19
|
||||
set_io spi_cs 16
|
||||
set_io uart_tx 21
|
||||
set_io uart_rx 13
|
||||
set_io usb_dn 37
|
||||
set_io usb_dp 34
|
||||
set_io usb_dp_pu 35
|
||||
set_io usb_dn_pu 36
|
||||
set_io dbg_1 20
|
||||
set_io dbg_2 12
|
||||
set_io dbg_3 11
|
||||
set_io dbg_4 25
|
||||
set_io dbg_5 10
|
||||
set_io dbg_6 9
|
||||
15
verilog-blink/pcf/fomu-hacker.pcf
Normal file
15
verilog-blink/pcf/fomu-hacker.pcf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
set_io rgb0 A5
|
||||
set_io rgb1 B5
|
||||
set_io rgb2 C5
|
||||
set_io clki F5
|
||||
set_io spi_mosi F1
|
||||
set_io spi_miso E1
|
||||
set_io spi_clk D1
|
||||
set_io spi_cs C1
|
||||
set_io user_1 F4
|
||||
set_io user_2 E5
|
||||
set_io user_3 E4
|
||||
set_io user_4 F2
|
||||
set_io usb_dn A2
|
||||
set_io usb_dp A4
|
||||
set_io usb_dp_pu D5
|
||||
29
verilog-blink/pcf/fomu-pvt1.pcf
Normal file
29
verilog-blink/pcf/fomu-pvt1.pcf
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
set_io rgb0 A5
|
||||
set_io rgb1 B5
|
||||
set_io rgb2 C5
|
||||
set_io pmod_1 E4
|
||||
set_io pmod_2 D5
|
||||
set_io pmod_3 E5
|
||||
set_io pmod_4 F5
|
||||
set_io pmoda_1 E4
|
||||
set_io pmoda_2 D5
|
||||
set_io pmoda_3 E5
|
||||
set_io pmoda_4 F5
|
||||
set_io clki F4
|
||||
set_io user_1 E4
|
||||
set_io user_2 D5
|
||||
set_io user_3 E5
|
||||
set_io user_4 F5
|
||||
set_io touch_1 E4
|
||||
set_io touch_2 D5
|
||||
set_io touch_3 E5
|
||||
set_io touch_4 F5
|
||||
set_io spi_mosi F1
|
||||
set_io spi_miso E1
|
||||
set_io spi_clk D1
|
||||
set_io spi_io2 F2
|
||||
set_io spi_io3 B1
|
||||
set_io spi_cs C1
|
||||
set_io usb_dn A2
|
||||
set_io usb_dp A1
|
||||
set_io usb_dp_pu A4
|
||||
Loading…
Reference in a new issue