Adding a more minimal Verilog example.
This commit is contained in:
parent
c3d049b04e
commit
03f75ee45a
4 changed files with 231 additions and 0 deletions
44
verilog-blink-minimal/Makefile
Normal file
44
verilog-blink-minimal/Makefile
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Simple Fomu Makefile
|
||||
# --------------------
|
||||
# This Makefile shows the steps to generate an DFU loadable image onto
|
||||
# Fomu hacker board.
|
||||
|
||||
|
||||
# Default target.
|
||||
all: blink.dfu
|
||||
@true
|
||||
|
||||
# Use *Yosys* generate the synthesized netlist
|
||||
# This is called the **synthesis** and **tech mapping** step.
|
||||
blink.json: blink.v
|
||||
yosys -p 'synth_ice40 -top top -json blink.json' blink.v
|
||||
|
||||
# Use **nextpnr** generate the FPGA configuration.
|
||||
# This is called the **place** and **route** step.
|
||||
blink.asc: blink.json blink.pcf
|
||||
nextpnr-ice40 --up5k --package uwg30 --json blink.json --pcf blink.pcf --asc blink.asc
|
||||
|
||||
# Use icepack to convert the FPGA configuration into a "bitstream" loadable onto the FPGA.
|
||||
# This is called the bitstream generation step.
|
||||
blink.bit: blink.asc
|
||||
icepack blink.asc blink.bit
|
||||
|
||||
# Use dfu-suffix to generate the DFU image from the FPGA bitstream.
|
||||
blink.dfu: blink.bit
|
||||
cp blink.bit blink.dfu
|
||||
dfu-suffix -v 1209 -p 70b1 -a blink.dfu
|
||||
|
||||
# Use df-util to load the DFU image onto the Fomu.
|
||||
load: blink.dfu
|
||||
dfu-util -D blink.dfu
|
||||
|
||||
.PHONY: load
|
||||
|
||||
# Cleanup the generated files.
|
||||
clean:
|
||||
-rm blink.json # Generate netlist
|
||||
-rm blink.asc # FPGA configuration
|
||||
-rm blink.bit # FPGA bitstream
|
||||
-rm blink.dfu # DFU image loadable onto the Fomu
|
||||
|
||||
.PHONY: load
|
||||
6
verilog-blink-minimal/README.md
Normal file
6
verilog-blink-minimal/README.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Minimal Verilog Example
|
||||
|
||||
A more minimal Verilog example.
|
||||
|
||||
Unlike the example in ../verilog-blink it **only** works on the **Fomu hacker
|
||||
board**.
|
||||
16
verilog-blink-minimal/blink.pcf
Normal file
16
verilog-blink-minimal/blink.pcf
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# Configuration for the Fomu hacker board.
|
||||
set_io rgb0 A5 # Blue LED
|
||||
set_io rgb1 B5 # Green LED
|
||||
set_io rgb2 C5 # Red LED
|
||||
set_io clki F5 # Clock input from 48MHz Oscillator
|
||||
set_io spi_mosi F1 # SPI Master Out, Slave In Pin
|
||||
set_io spi_miso E1 # SPI Master In, Slave Out Pin
|
||||
set_io spi_clk D1 # SPI Master Clock Output Pin
|
||||
set_io spi_cs C1 # SPI Chip Select
|
||||
set_io user_1 F4 # User touch pad 1
|
||||
set_io user_2 E5 # User touch pad 2
|
||||
set_io user_3 E4 # User touch pad 3
|
||||
set_io user_4 F2 # User touch pad 4
|
||||
set_io usb_dn A2 # USB D- pad
|
||||
set_io usb_dp A4 # USB D+ pad
|
||||
set_io usb_dp_pu D5 # USB D+ pull up (indicates device connected)
|
||||
165
verilog-blink-minimal/blink.v
Normal file
165
verilog-blink-minimal/blink.v
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
// 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.
|
||||
//
|
||||
//
|
||||
`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 (
|
||||
// 48MHz Clock input
|
||||
// --------
|
||||
input clki,
|
||||
// LED outputs
|
||||
// --------
|
||||
output rgb0,
|
||||
output rgb1,
|
||||
output rgb2,
|
||||
// User touchable pins
|
||||
// --------
|
||||
// Connect 1-2 to enable blue LED
|
||||
input user_1,
|
||||
output user_2,
|
||||
// Connect 3-4 to enable red LED
|
||||
output user_3,
|
||||
input user_4,
|
||||
// USB Pins (which should be statically driven if not being used).
|
||||
// --------
|
||||
output usb_dp,
|
||||
output usb_dn,
|
||||
output usb_dp_pu
|
||||
);
|
||||
|
||||
// Drive the USB outputs to constant values as they are not in use.
|
||||
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),
|
||||
);
|
||||
|
||||
wire enable_blue = ~user_1_pulled;
|
||||
wire enable_red = ~user_4_pulled;
|
||||
|
||||
// Use system PLL module to divide system clock
|
||||
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
|
||||
) pll (
|
||||
.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
|
||||
|
||||
// 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";
|
||||
|
||||
// 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)
|
||||
);
|
||||
|
||||
// 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_16MA_06MA; // Blue - Needs more current.
|
||||
defparam RGBA_DRIVER.RGB1_CURRENT = RGBA_CURRENT_08MA_04MA; // Red
|
||||
defparam RGBA_DRIVER.RGB2_CURRENT = RGBA_CURRENT_08MA_04MA; // Green
|
||||
|
||||
endmodule
|
||||
Loading…
Reference in a new issue