Project F

News: May 2021

Published · Updated

As well as the occasional big blog post, I make many smaller FPGA discoveries and Project F updates each month. I thought it would be interesting to share a few of these in a monthly news post. What do you think? Let me know via or open an issue on GitHub.

Read the June 2021 news or see the news archive.


In May, I added two blog posts: Hello Arty Part 3 and FPGA Sine Lookup Table.

Hello Arty is my introductory series for the Digilent Arty board. In Hello Arty Part 3, we design a countdown timer and a traffic light control system using finite state machines. We also cover enums, case statements, button debouncing, and shift registers. I think this part is overly long, and I still haven’t covered test benches, so I am considering a fourth part for this series.

Sine Lookup Table is a new post this month. We pre-calculate sine values with a Python script and then load them into a ROM with a simple Verilog module. For many applications, pre-calculated sine values are more than good enough. I’ve been using the lookup table for simple 3D graphics, which I’ll write about at some point.

Sine & Cosine

Graph image by Geek3 in the public domain.


I dipped my toes in the waters of YouTube with a little demo reel: FPGA Graphics Demo 1.

All the graphics in this demo reel are generated by an Artix-7 FPGA using designs from FPGA Graphics. I sped up some of the sequences during video editing, and I’m using pre-recorded music, but otherwise, what you see is exactly as it came from the FPGA.

Stay tuned for more videos over the summer.

FPGA Graphics

The FPGA Graphics tutorial series has been my main focus for the past year. This month I made a few useful improvements to existing designs from this series.

Draw Line Performance

Many graphics routines depend on line drawing. This month, I improved the performance of the Bresenham’s line module: The cube and triangle demos from Lines and Triangles now comfortably meet timing on iCEBreaker, allowing me to close issue #37.

Ad Astra on iCEBreaker

The Ad Astra blog post includes a greetings demo using sprites to draw text characters. This design was one of the earliest created for my FPGA Graphics series, and its performance has never been great on iCEBreaker.

I recently learnt about Yosys support for ABC logic library v9 from a conversation on 1BitSquared Discord. I tried ABC v9 on several designs with variable results: logic usage was down significantly on all designs, but some designs suffered performance regressions. Happily, Ad Astra on iCEBreaker was one of the designs that showed a significant improvement in timing, allowing me to close issue #32.

If you want to try ABC v9 with your iCEBreaker designs use: synth_ice40 -abc9 -device u, and you can see a complete example in the Ad Astra Makefile (since removed, see below).

FPGA Ad Astra

NB. I subsequently removed the iCEBreaker version of Ad Astra as I couldn’t get it to work well. Sorry about that.

The Sky is Falling

The hedgehog sprite from Hardware Sprites walks under a cloudless sky.

Hedgehog walking under the sky

My original sky design used combinational logic (nextpnr timings are for iCE40UP5K):

    logic [11:0] bg_colr;
    always_comb begin
        bg_colr = 12'h260;  // default
        if (sy < 80)       bg_colr = 12'h239;
        else if (sy < 140) bg_colr = 12'h24A;
        else if (sy < 190) bg_colr = 12'h25B;
        else if (sy < 230) bg_colr = 12'h26C;
        else if (sy < 265) bg_colr = 12'h27D;
        else if (sy < 295) bg_colr = 12'h29E;
        else if (sy < 320) bg_colr = 12'h2BF;

// Info: 13.7 ns logic, 23.9 ns routing
// Info: Max frequency for clock 'clk_pix': 26.63 MHz (PASS at 25.14 MHz)

I recently switched to a new registered version that cut routing time in half!

    logic [11:0] bg_colr;
    always_ff @(posedge clk_pix) begin
        if (line) begin
            if      (sy == 0)   bg_colr <= 12'h239;
            else if (sy == 80)  bg_colr <= 12'h24A;
            else if (sy == 140) bg_colr <= 12'h25B;
            else if (sy == 190) bg_colr <= 12'h26C;
            else if (sy == 230) bg_colr <= 12'h27D;
            else if (sy == 265) bg_colr <= 12'h29E;
            else if (sy == 295) bg_colr <= 12'h2BF;
            else if (sy == 320) bg_colr <= 12'h260;

// Info: 11.9 ns logic, 11.8 ns routing
// Info: Max frequency for clock 'clk_pix': 42.14 MHz (PASS at 25.14 MHz)

The maximum frequency of the complete hedgehog design increased from a marginal 26.63 MHz to a comfortable 42.14 MHz. The moral of this story: beware of seemingly simple combinational logic tanking your timing.

For the complete designs, see the Hardware Sprite design files (GitHub).

Bits & Tips

nextpnr Clock Constraint

You can set a nextpnr clock constraint in your PCF file using set_frequency.

For iCEBreaker, I use:

## Board Clock: 12 MHz
set_frequency  clk_12m      12
set_io -nowarn clk_12m      35

FPGA and RISC-V links that caught my eye:

For more great links, try Recommended FPGA Sites.

And Finally

I’m a sucker for Amiga documentaries, and Kim Justice’s The Story and Games of the Bitmap Brothers is one of the best.

Read the June 2021 news or see the news archive.

Sponsor Project F
If you like what I do, consider sponsoring me on GitHub.
I use contributions to spend more time creating open-source FPGA designs and tutorials.