-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
412 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,4 +43,5 @@ Languages and generators | |
|
||
verilog | ||
vhdl | ||
mixed-hdl | ||
migen |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
.. _HDLs:mixed: | ||
|
||
Mixed HDL on Fomu | ||
----------------- | ||
|
||
.. IMPORTANT:: The pre-built toolchain we publish does not include `GHDL <https://github.com/ghdl>`_ | ||
yet. These examples use `open-tool-forge/fpga-toolchain <https://github.com/open-tool-forge/fpga-toolchain>`_ | ||
instead. The installation procedure does not change: retrieve the package | ||
for your platform, extract it, and add it to the PATH. | ||
Note that the set of tools used for synthesis and P&R is the same: Yosys | ||
and nextpnr. It's just a different packaging which includes GHDL too. | ||
There is work in progress for including *fpga-toolchain* in *Fomu toolchain* | ||
(see `im-tomu/fomu-toolchain#20 <https://github.com/im-tomu/fomu-toolchain/pull/20>`_). | ||
|
||
.. 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`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# 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 | ||
|
||
GHDL ?= ghdl | ||
GHDL_FLAGS += --std=08 | ||
|
||
# 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 = 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
library ieee; | ||
context ieee.ieee_std_context; | ||
|
||
use work.components.all; | ||
|
||
entity Fomu_Blink is | ||
port ( | ||
-- 48MHz Clock input | ||
clki: in std_logic; | ||
|
||
-- LED outputs | ||
rgb0: out std_logic; | ||
rgb1: out std_logic; | ||
rgb2: out std_logic; | ||
|
||
-- USB Pins (which should be statically driven if not being used) | ||
usb_dp: out std_logic; | ||
usb_dn: out std_logic; | ||
usb_dp_pu: out std_logic | ||
); | ||
end; | ||
|
||
architecture arch of Fomu_Blink is | ||
|
||
signal clk: std_logic; | ||
signal color: std_logic_vector(2 downto 0) := (others=>'0'); | ||
|
||
component clkgen | ||
port ( | ||
clk: in std_logic; | ||
cnt: out std_logic_vector(2 downto 0) | ||
); | ||
end component; | ||
|
||
begin | ||
|
||
-- 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. | ||
usb_dp <= '0'; | ||
usb_dn <= '0'; | ||
usb_dp_pu <= '0'; | ||
|
||
-- Instantiate clkgen for reducing the system clock | ||
clk_generator: component clkgen | ||
port map ( | ||
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 | ||
rgba_driver: SB_RGBA_DRV | ||
generic map ( | ||
CURRENT_MODE => "0b1", -- half current | ||
RGB0_CURRENT => "0b000011", -- 4 mA | ||
RGB1_CURRENT => "0b000011", -- 4 mA | ||
RGB2_CURRENT => "0b000011" -- 4 mA | ||
) | ||
port map ( | ||
CURREN => '1', | ||
RGBLEDEN => '1', | ||
RGB0PWM => color(2), | ||
RGB1PWM => color(1), | ||
RGB2PWM => color(0), | ||
RGB0 => rgb0, | ||
RGB1 => rgb1, | ||
RGB2 => rgb2 | ||
); | ||
|
||
end; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
module clkgen ( | ||
input wire clk, | ||
output wire [2:0] cnt | ||
); | ||
|
||
// Connect to system clock (with buffering) | ||
wire clko; | ||
SB_GB clk_gb ( | ||
.USER_SIGNAL_TO_GLOBAL_BUFFER(clk), | ||
.GLOBAL_BUFFER_OUTPUT(clko) | ||
); | ||
|
||
// Use counter logic to divide system clock. The clock is 48 MHz, | ||
// so we divide it down by 2^28. | ||
reg [28:0] counter = 0; | ||
always @(posedge clko) begin | ||
counter <= counter + 1; | ||
end | ||
assign cnt = counter[25:23]; | ||
|
||
endmodule |
Oops, something went wrong.