Skip to content

Commit

Permalink
add mixed-hdl/blink
Browse files Browse the repository at this point in the history
  • Loading branch information
umarcor committed Oct 12, 2020
1 parent 48f3e10 commit 87d1652
Show file tree
Hide file tree
Showing 10 changed files with 421 additions and 10 deletions.
30 changes: 20 additions & 10 deletions .github/tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,6 @@ echo "TOOLCHAIN_PATH: $TOOLCHAIN_PATH"
export PATH=$TOOLCHAIN_PATH/bin:$PATH
export GHDL_PREFIX=$TOOLCHAIN_PATH/lib/ghdl

echo '::group::VHDL Blink example'
(

set -x
cd vhdl/blink
make FOMU_REV=pvt
file blink.dfu
)
echo '::endgroup::'

echo '::group::RISC-V C Example'
(
set -x
Expand Down Expand Up @@ -63,6 +53,26 @@ echo '::group::Verilog Blink (expanded) example for PVT board'
)
echo '::endgroup::'

echo '::group::VHDL Blink example'
(

set -x
cd vhdl/blink
make FOMU_REV=pvt
file blink.dfu
)
echo '::endgroup::'

echo '::group::Mixed HDL Blink example'
(

set -x
cd mixed-hdl/blink
make FOMU_REV=pvt
file blink.dfu
)
echo '::endgroup::'

echo '::group::LiteX example for Hacker'
(
set -x
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ The contents of this workshop is published at [workshop.fomu.im](https://worksho
of the workshop](https://workshop.fomu.im/en/latest/verilog.html).
- [vhdl](./vhdl) - The files required for the [VHDL on Fomu section
of the workshop](https://workshop.fomu.im/en/latest/vhdl.html).
- [mixed-hdl](./mixed-hdl) - The files required for the [Mixed HDL on Fomu section
of the workshop](https://workshop.fomu.im/en/latest/mixedhdl.html).

# Development

Expand Down
1 change: 1 addition & 0 deletions docs/hdl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ Languages and generators

verilog
vhdl
mixed-hdl
migen
80 changes: 80 additions & 0 deletions docs/mixed-hdl.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
.. _HDLs:mixed:

Mixed HDL on Fomu
-----------------

.. HINT:: It is strongly suggested to get familiar with :ref:`HDLs:Verilog` and :ref:`HDLs:VHDL`
examples before tinkering with these mixed language use cases.


“Hello world!” - Blink a LED
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The canonical “Hello, world!” of hardware is to blink a LED. The
directory ``mixedhdl/blink`` contains a VHDL + Verilog example of a blink
project. This takes the 48 MHz clock and divides it down by a large
number so you get an on/off pattern.

Enter the ``mixedhdl/blink`` directory and build the demo by using ``make``:

.. session:: shell-session

$ make FOMU_REV=$FOMU_REV
...
Info: Max frequency for clock 'clk_generator.clko': 73.26 MHz (PASS at 12.00 MHz)

Info: Max delay posedge clk_generator.clko -> <async>: 3.15 ns

Info: Slack histogram:
Info: legend: * represents 1 endpoint(s)
Info: + represents [1,1) endpoint(s)
Info: [ 69683, 70208) |**
Info: [ 70208, 70733) |
Info: [ 70733, 71258) |**
Info: [ 71258, 71783) |**
Info: [ 71783, 72308) |**
Info: [ 72308, 72833) |**
Info: [ 72833, 73358) |
Info: [ 73358, 73883) |**
Info: [ 73883, 74408) |*
Info: [ 74408, 74933) |**
Info: [ 74933, 75458) |**
Info: [ 75458, 75983) |*
Info: [ 75983, 76508) |*
Info: [ 76508, 77033) |**
Info: [ 77033, 77558) |**
Info: [ 77558, 78083) |*
Info: [ 78083, 78608) |
Info: [ 78608, 79133) |*************************
Info: [ 79133, 79658) |**
Info: [ 79658, 80183) |***
22 warnings, 0 errors
icepack blink.asc blink.bit
cp blink.bit blink.dfu
dfu-suffix -v 1209 -p 70b1 -a blink.dfu
dfu-suffix (dfu-util) 0.9
Copyright 2011-2012 Stefan Schmidt, 2013-2014 Tormod Volden
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Suffix successfully added to file
$

You can then load ``blink.dfu`` onto Fomu by using ``make load`` or the same
``dfu-util -D`` command we’ve been using so far. You should see a blinking pattern of
varying color on your Fomu, indicating your bitstream was successfully loaded.

If you take a closer look at the sources in ``mixedhdl/blink``, you will find that
modules/components ``blink`` and ``clkgen`` are written both in VHDL and Verilog.
The Makefile uses ``blink.vhd`` and ``clkgen.v`` by default. However, any of the
following cases produce the same result:

- ``blink.vhd`` + ``clkgen.v``
- ``blink.v`` + ``clkgen.vhdl``
- ``blink.vhd`` + ``clkgen.vhdl``
- ``blink.v`` + ``clkgen.v``

You can modify variables `VHDL_SYN_FILES` and ``VERILOG_SYN_FILES`` in the Makefile
for trying other combinations. For a better understanding, it is suggested to compare
these modules with the single file solutions in :ref:`HDLs:Verilog` and :ref:`HDLs:VHDL`.
82 changes: 82 additions & 0 deletions mixed-hdl/blink/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Different Fomu hardware revisions are wired differently and thus
# require different configurations for yosys and nextpnr.
# Configuration is performed by setting the environment variable FOMU_REV accordingly.
ifeq ($(FOMU_REV),evt1)
YOSYSFLAGS?= -D EVT=1
PNRFLAGS ?= --up5k --package sg48 --pcf ../../pcf/fomu-evt2.pcf
else ifeq ($(FOMU_REV),evt2)
YOSYSFLAGS?= -D EVT=1
PNRFLAGS ?= --up5k --package sg48 --pcf ../../pcf/fomu-evt2.pcf
else ifeq ($(FOMU_REV),evt3)
YOSYSFLAGS?= -D EVT=1
PNRFLAGS ?= --up5k --package sg48 --pcf ../../pcf/fomu-evt3.pcf
else ifeq ($(FOMU_REV),hacker)
YOSYSFLAGS?= -D HACKER=1
PNRFLAGS ?= --up5k --package uwg30 --pcf ../../pcf/fomu-hacker.pcf
else ifeq ($(FOMU_REV),pvt)
YOSYSFLAGS?= -D PVT=1
PNRFLAGS ?= --up5k --package uwg30 --pcf ../../pcf/fomu-pvt.pcf
else
$(error Unrecognized FOMU_REV value. must be "evt1", "evt2", "evt3", "pvt", or "hacker")
endif

# VHDL top with instantiated Verilog
VHDL_SYN_FILES = ../../vhdl/sb_ice40_components.vhd blink.vhd
VERILOG_SYN_FILES = clkgen.v

# Verilog top with instantiated VHDL
#VHDL_SYN_FILES = ../../vhdl/sb_ice40_components.vhd clkgen.vhd
#VERILOG_SYN_FILES = blink.v

GHDL_FLAGS += --std=08
GHDL ?= ghdl
GHDLSYNTH ?= ghdl
YOSYS ?= yosys
NEXTPNR ?= nextpnr-ice40
ICEPACK ?= icepack

# Default target: run all required targets to build the DFU image.
all: blink.dfu
@true

.DEFAULT: all

# Use *Yosys* to generate the synthesized netlist.
# This is called the **synthesis** and **tech mapping** step.
blink.json: $(VHDL_SYN_FILES) $(VERILOG_SYN_FILES)
$(YOSYS) $(YOSYSFLAGS) \
-p \
"$(GHDLSYNTH) $(GHDL_FLAGS) $(VHDL_SYN_FILES) -e; \
synth_ice40 \
-top Fomu_Blink \
-json $@" -q $(VERILOG_SYN_FILES) 2>&1 | tee yosys-report.txt

# Use **nextpnr** to generate the FPGA configuration.
# This is called the **place** and **route** step.
blink.asc: blink.json
$(NEXTPNR) \
$(PNRFLAGS) \
--json $< \
--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) $< $@

# Use dfu-suffix to generate the DFU image from the FPGA bitstream.
blink.dfu: blink.bit
cp $< $@
dfu-suffix -v 1209 -p 70b1 -a $@

# Use df-util to load the DFU image onto the Fomu.
load: blink.dfu
dfu-util -D $<

.PHONY: load

# Cleanup the generated files.
clean:
rm -fr *.cf *.json *-report.txt *.asc *.bit *.dfu

.PHONY: clean
22 changes: 22 additions & 0 deletions mixed-hdl/blink/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Minimal Mixed HDL Example (VHDL and Verilog)

A minimal mixed HDL example which simply blinks the RGB LEDs at different
frequencies.

This example contains equivalent sources in VHDL and Verilog, which can be
combined freely:

- `blink.vhd` + `clkgen.v`
- `blink.v` + `clkgen.vhdl`
- `blink.vhd` + `clkgen.vhdl`
- `blink.v` + `clkgen.v`

All four cases produce exactly the same result, because the same design is
described regardless of the HDL language used. In the makefile, the first
case is built by default.

## Using

Type `make` to build the DFU image.
Type `make load` to load the DFU image onto the Fomu board.
Type `make clean` to remove all the generated files.
77 changes: 77 additions & 0 deletions mixed-hdl/blink/blink.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Simple tri-colour LED blink example.

// Correctly map pins for the iCE40UP5K SB_RGBA_DRV hard macro.
// The variables EVT, PVT and HACKER are set from the Makefile.
`ifdef EVT
`define BLUEPWM RGB0PWM
`define REDPWM RGB1PWM
`define GREENPWM RGB2PWM
`elsif HACKER
`define BLUEPWM RGB0PWM
`define GREENPWM RGB1PWM
`define REDPWM RGB2PWM
`elsif PVT
`define GREENPWM RGB0PWM
`define REDPWM RGB1PWM
`define BLUEPWM RGB2PWM
`else
`error_board_not_supported
`endif

module Fomu_Blink (
// 48MHz Clock input
// --------
input clki,
// LED outputs
// --------
output rgb0,
output rgb1,
output rgb2,
// USB Pins (which should be statically driven if not being used).
// --------
output usb_dp,
output usb_dn,
output usb_dp_pu
);

// Assign USB pins to "0" so as to disconnect Fomu from
// the host system. Otherwise it would try to talk to
// us over USB, which wouldn't work since we have no stack.
assign usb_dp = 1'b0;
assign usb_dn = 1'b0;
assign usb_dp_pu = 1'b0;

wire [2:0] color;

// Instantiate clkgen for reducing the system clock
clkgen clk_generator (
.clk(clki),
.cnt(color)
);

// Instantiate iCE40 LED driver hard logic, connecting up
// counter state and LEDs.
//
// Note that it's possible to drive the LEDs directly,
// however that is not current-limited and results in
// overvolting the red LED.
//
// See also:
// https://www.latticesemi.com/-/media/LatticeSemi/Documents/ApplicationNotes/IK/ICE40LEDDriverUsageGuide.ashx?document_id=50668
SB_RGBA_DRV #(
.CURRENT_MODE("0b1"), // half current
.RGB0_CURRENT("0b000011"), // 4 mA
.RGB1_CURRENT("0b000011"), // 4 mA
.RGB2_CURRENT("0b000011") // 4 mA
) RGBA_DRIVER (
.CURREN(1'b1),
.RGBLEDEN(1'b1),
.`BLUEPWM(color[2]), // Blue
.`REDPWM(color[1]), // Red
.`GREENPWM(color[0]), // Green
.RGB0(rgb0),
.RGB1(rgb1),
.RGB2(rgb2)
);

endmodule
Loading

0 comments on commit 87d1652

Please sign in to comment.